JVM GC原理

了解JVM GC原理非常重要,对于系统调优非常有用。如果一个系统频繁发生FULL GC,那么会造成系统响应卡顿,更严重的时候会导致系统崩溃。

JVM的内存空间

JVM的内存空间,从大的层面上来分析包含:新生代空间(Young)和老年代空间(Old)。新生代空间(Young)又被分为2个部分(Eden区域、Survivous区域)和3个板块(1个Eden区域和2个Survivous区域)

在这里插入图片描述
下边来看下具体每部分都是用来干什么的。

1)Eden(伊甸园)区域:用来存放使用new或者newInstance等方式创建的对象,默认这些对象都是存放在Eden区,除非这个对象太大,或者超出了设定的阈值-XX:PretenureSizeThresold,这样的对象会被直接分配到Old区域。

2)2个Survivous(幸存)区域:一般称为S0,S1,理论上他们一样大。

下边将会讲解它们如何工作的。

第一次GC:

在不断创建对象的过程中,当Eden区域被占满,此时会开始做Young GC也叫Minor GC

1)第一次GC时Survivous中S0区和S1区都为空,将其中一个作为To Survivous(用来存储Eden区域执行GC后不能被回收的对象)。比如:将S0作为To Survivous,则S1为From Survivous。

2)将Eden区域经过GC不能被回收的对象存储到To Survivous(S0)区域(此时Eden区域的内存会在垃圾回收的过程中全部释放),但如果To Survivous(S0)被占满了,Eden中剩下不能被回收对象只能存放到Old区域。

3)将Eden区域空间清空,此时From Survivous区域(S1)也是空的。

4)S0与S1互相切换标签,S0为From Survivous,S1为To Survivous。

在这里插入图片描述

第二次GC:

当第二次Eden区域被占满时,此时开始做GC

1)将Eden和From Survivous(S0)中经过GC未被回收的对象迁移到To Survivous(S1),如果To Survious(S1)区放不下,将剩下的不能回收对象放入Old区域;

2)将Eden区域空间和From Survivous(S0)区域空间清空;

3)S0与S1互相切换标签,S0为To Survivous,S1为From Survivous。
在这里插入图片描述

第三次,第四次一次类推,始终保证S0和S1有一个空的,用来存储临时对象,用于交换空间的目的。反反复复多次没有被淘汰的对象,将会被放入Old区域中,默认15次(由参数–XX:MaxTenuringThreshold=15 决定)。

GC中相关问题

问题1:怎么定义活着的对象?

从根引用开始,对象的内部属性可能也是引用,只要能级联到的都被认为是活着的对象。

问题2:什么是根?

本地变量引用,操作数栈引用,PC寄存器,本地方法栈引用等这些都是根。

问题3:对象进入Old区域有什么坏处?

Old区域一般称为老年代,老年代与新生代不一样。新生代,我们可以认为存活下来的对象很少,而老年代则相反,存活下来的对象很多,所以JVM的堆内存,才是我们通常关注的主战场,因为这里面活着的对象非常多,所以发生一次FULL GC,来找出来所有存活的对象是非常耗时的,因此,我们应该避免FULL GC的发生。

问题4:S0和S1一般多大,靠什么参数来控制,有什么变化?

一般来说很小,我们大概知道它与Young差不多相差一倍的比例,设置的参数主要有两个:

-XX:SurvivorRatio=8
-XX:InitialSurvivorRatio=8
第一个参数(-XX:SurvivorRatio)是Eden和Survivous区域比重(注意Survivous一般包含两个区域S0和S1,这里是一个Survivous的大小)。如果将-XX:SurvivorRatio=8设置为8,则说明Eden区域是一个Survivous区的8倍,换句话说S0或S1空间是整个Young空间的1/10,剩余的8/10由Eden区域来使用。

第二个参数(-XX:InitialSurvivorRatio)是Young/S0的比值,当其设置为8时,表示S0或S1占整个Young空间的1/8(或12.5%)。

问题5:一个对象每次Minor GC时,活着的对象都会在S0和S1区域转移,讲过MInor GC多少次后,会进入Old区域呢?

默认是15次,参数设置

–XX:MaxTenuringThreshold=15
,计数器会在对象的头部记录它的交换次数。

问题6:为什么发生FULL GC会带来很大的危害?

在发生FULL GC的时候,意味着JVM会安全的暂停所有正在执行的线程(Stop The World),来回收内存空间,在这个时间内,所有除了回收垃圾的线程外,其他有关JAVA的程序,代码都会静止,反映到系统上,就会出现系统响应大幅度变慢,卡机等状态。

举个通俗易懂点的例子,就是在一个房间里,如果有一个人,不停的扔垃圾,然后有一个清洁工不停扫垃圾,这时候,我们的系统是OK的,因为基本不会出现垃圾堆满房间的情景,而且因为清洁工可以对付过来,假设现在有10个人不停扔垃圾,那么就房间就会很快被堆满,这时候清洁工,由于工作不过来了,大声吼一声,你们都暂停3分钟,别再扔了,我先把这个房间打扫完,你们才可以扔。
在这个场景中,一个人扔,一个人扫,就类似于Minor GC,这时候,并不会影响扔垃圾的人,然后一旦10个人同时仍,而且很快就没地方仍了,这时候,就会触发Full GC,然后JVM下令,你们暂时都别仍了,等我什么时候回收完垃圾了,你们在仍,现在大家清楚了吧,所谓的10个人,就是类似我们成千上百的java类,在不停的执行任务,所谓的清洁工,就是我们的GC机制,所以,大家在平时编码的时候,一定注意尽量少造点垃圾对象,这样触发FULL GC的几率,才会变小。

热门文章

暂无图片
编程学习 ·

NASM系列啊

文章目录NASM是什么?NASM下载与安装 NASM是什么?The Netwide Assembler, 一款基于80x86和x86-64平台的汇编语言编译程序, 是为了实现编译器程序跨平台和模块化的特性。 NASM支持大量的文件格式,包括Linux,*BSD,a.out,ELF,COFF,Mach−O,Microsoft 16−bit OBJ,Win32…
暂无图片
编程学习 ·

STM32开放式开发环境:释放创造力

市场上涌现各种价格亲民的经济型微控制器,助力新一代开发者创造令人兴奋的新型嵌入式应用。如今的开发工具非常好用,软硬件均呈现模块化趋势,插接安装简单容易,使得产品设计评估和原型开发周期大幅缩短。STM32开放式开发环境是业内独一无二的软硬件开发平台,堆叠式插接电路…
暂无图片
编程学习 ·

Embind用于将C ++和JavaScript交互

官方文档EmbindEmbind is used to bind C++ functions and classes to JavaScript, so that the compiled code can be used in a natural way by “normal” JavaScript. Embind also supports calling JavaScript classes from C++.Embind has support for binding most C++ …
暂无图片
编程学习 ·

「a」 超链接标签

a标签常用的属性:href : 用于指定链接的资源target: 设置打开新资源的目标。 _Blank 在独立的窗口上打开新资源 _self 在当前窗口打开新资源file: file协议(文件协议)这种协议主要是用于搜索本地机器的资源文件的。格式:file:\\\f:\美女\1.jpg a标签的原理:1. a标…
暂无图片
编程学习 ·

easyui datagrid deleteRow(删除行)的BUG

有时候想临时保存一些数据,等确定好后在批量一次提交,但EasyUI datagrid 用的时候添加可以正常,如果从中间删除那行号就全乱了。导致删除的时候有可能删除上一行数据。function addFileRow(){$(#FileTable).datagrid(appendRow,{ File_Name:"aaaa",File_Path:&qu…
暂无图片
编程学习 ·

火箭少女101毕业,rocketgirls.fans粉丝站上线震撼饭圈

2年前的2018年6月23日晚:经过一百零四天的艰苦训练和比赛,由457家公司、13778名练习生中层层挑选出的11名女孩站上成团出道位,组成为期2年的限定女团,火箭少女101成团出道。两年后的2020年6月23日晚:火箭少女101的2年限定组合期限已到,晚上8点 “遇见再见”火箭少女101告…
暂无图片
编程学习 ·

Pandas 删除指定行

定位要删除的行 需求:删除指定列中NaN所在行。如下图,’open‘ 列中有一行为NaN,定位到它,然后删除。定位:df[np.isnan(df[open])].index # 这样即可定位到所在行的index,然后对该index进行drop操作即可删除行 df.drop(df[np.isnan(df[open])].index, inplace=True)# 直接…
暂无图片
编程学习 ·

Xavier初始化和He初始化

转自https://blog.csdn.net/xxy0118/article/details/84333635Xavier初始化: 条件:正向传播时,激活值的方差保持不变;反向传播时,关于状态值的梯度的方差保持不变。初始化方法:W∼U[−6√ni+ni+1√,6√ni+ni+1√] W∼U[−ni​+ni+1​​6​​,ni​+ni+1​​6​​]假设激活函…
暂无图片
编程学习 ·

Spring Boot + RabbitMQ 配置参数解释

application.properties配置文件写法#rabbitmq spring.rabbitmq.virtual-host=/ spring.rabbitmq.host=192.168.124.20 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.rabbitmq.listener.concurrency=10 spring.rabbitmq.l…
暂无图片
编程学习 ·

CentOS系统安装好之后输入ifconfig指令无法查看ip解决办法

CentOS系统安装好之后输入ifconfig指令无法查看ip解决办法 第一次使用虚拟机安装CentOS系统,安装完之后想要通过Xshell连接Linux系统,在输入ifconfig指令后,无法查看到ip地址,也就无法通过ip地址连接Linux系统 本人经过多次百度,找了很多的解决办法都无法解决问题,但也发现了无…
暂无图片
编程学习 ·

git学习日志-标签

git也可以像svn一样打标签,以此来标记发布节点,以示重要性。 对标签的操作,一般包括: 1. 列出标签 2. 创建标签 3. 删除标签 4. 检出标签 一、列出标签 执行git tag命令,就可以看到当前仓库中已经打过的标签。注意: 这个命令会以字母顺序列出标签。 也可以加上-l或--list…
暂无图片
编程学习 ·

mybati中动态标签「if」没有生效的原因

一、问题: <if test="carrier != null and carrier != and carrier !=0">AND CARRIER = #{carrier} </if>我们在接口设置传入的字段类型为String,要在carrier字段不为null,空字符串,和”0“的时候增加以上条件,但是以上当carrier等于"0"时…
暂无图片
编程学习 ·

小样本如何选择学习方法

小样本该如何学习: https://zhuanlan.zhihu.com/p/152122909 小样本学习专栏:https://zhuanlan.zhihu.com/c_1258398000180768768 若喜欢,请关注知乎专栏账号,后面持续更新小样本学习相关内容。
暂无图片
编程学习 ·

01 HTML知识笔记(标签—布局)

本人使用的是sublime text3编辑器,这款软件的汉化破解版会随资料一起上传的😀然后找到的一些比较好的博文同大家一起share!!!Sublime text 3 汉化 破解版 分享Sublime Text3快捷键大全用sublime text3编写的html网页用浏览器打开出现中文乱码的原理及解决方法目录一、htm…
暂无图片
编程学习 ·

2019ICPC南昌

2019ICPC南昌 重现C. And and Pair 题意: 给定一个很大的数n的二进制表示s(也就是01串),计算满足条件的数对<i,j>的数量 条件: 0<=j<=i<=n i&n=i i&j=0 其中&符号表示位运算与 答案对1e9+7取模 数据范围:|s|<=1e5 解法: 很容易看出可以用数…
暂无图片
编程学习 ·

01_第一章_数据类型_02_变量的类型决定了什么

变量的类型决定了什么 高级语言为什么要区分数据类型为了更有效地组织数据,规范数据的使用 有助于提高程序的可读性,方便用户使用在程序设计语言中引入数据类型的好处带来了程序的简明性和数据的可靠性。 有助于提高程序的执行效率,节省内存空间C语言的数据类型 基本类型整型…
暂无图片
编程学习 ·

快手2020校园招聘秋招笔试--工程B试卷

攻击者使用无效IP地址,利用TCP连接的三次握手过程,连续发送会话请求,使受害主机处于开放会话的请求之中,直至连接超时,最终因耗尽资源而停止响应。这种攻击被称为A. DNS欺骗攻击 B. DDoS攻击 C. SYN Flooding攻击 D. 重放攻击DNS欺骗攻击:DNS(Domin Name Sever)是域名服…