您好,欢迎来到榕意旅游网。
搜索
您的当前位置:首页JVM内功增强篇

JVM内功增强篇

来源:榕意旅游网

Day02 ------JVM内功增强篇

01 结合Eden、S0、S1和Old区,描述一下一个对象创建的过程???
02 怎样确定一个对象为垃圾?
03 常用的垃圾回收算法有哪些?并且有什么优缺点???

答:
Eden、S0、S1(8:1:1)
01、一个对象创建的过程
一个对象被创建—》进入Eden区,Eden区内存不够且该对象存活,使用标记-复制算法(特例:如对象在Eden区放不下,直接放到old区)把它复制到S0区,并清除Eden区不可达的对象。如果S0区满了,该对象转到S1区(对象在S0、S1区来回切换)如多次GC后该对象任然存活(每垃圾回收一次仍然存活则count+)当count>15了,那么该对象直接放入old区。
特例:秒杀项目,一个对象在Eden区被创建后-----朝生夕死
一个对象初次创建存放到新生代的Eden区中,如果内存特别大,直接放到old区;
02、确定一个对象为垃圾
a、通过引用计数法确定一个对象是否为垃圾,存在循环引用就死循环了
b、可达性分析:如果不可达则为垃圾(通过类加载器不可达的,非static变量、非常量----不确定)
c、通过线程共享可以判读对象是否为垃圾;

**===========================================================
2、XXX对象上帝视角,经过一系列的链接,看能否到达该对象???
上帝视角的确定???
依据GC Root

1、类加载器、JVM本地变量表、静态变量、常量、本地方法栈变量

由他们出发可以到达该对象,这个对象就不是垃圾。

**

面试官说你背下来了???----------理直气壮地说

**

举例:

1标记存活对象;2清除垃圾对象;
分两步走:先标记需要清楚的对象,后清除–后统一清除被标记对象;
缺点:消耗时间,系统性能降低;容易产生垃圾碎片
使用场景:老年代使用;CMS垃圾收集器;G1垃圾收集器

{2} 标记-整理–Mark-Compact

1标记存活对象;2将存活对象放到连续的一段内存空间并清除垃圾对象;3整理之前存活对象的内存空间为连续空间;
优点:解决了空间碎片问题;
缺点:消耗时间,系统性能降低;
使用场景:老年代使用;

{3} 标记-复制–mark-copy

1将内存空间分成大小相等2份(左右两个区域:使用区;保留区);A区存放对象,A区内存满了将标记存活对象复制到B区,清除A区所有对象;
适用条件:新生代区,
缺点:内存利用率降低,不适用存活对象多的时候(降低系统性能)
使用场景:新生代使用,Eden;S0:S1-----from 和 to 关系轮换(标记复制)
知识总结:内存分为 新生代(Eden区+S0+S1)和老年代(old区),对象初次创建存放到新生代的Eden区中,如果内存特别大(800M,直接放到old区)
新生带:Minor GC + Major GC = Full Gc
不同场景使用不同垃圾收集器
按照新老年代分:
新生代:SerialGC器、ParNewGC器、Parallel ScanVengeGC器+G1 垃圾收集器
老年代:Serial old 垃圾收集器 、Parallel old垃圾收集器、CMS(Concurrent Mark Sweep—并发标记清除)垃圾收集器
其中G1算法新老年代都适用 Minor GC + Major GC = Full Gc
串行收集器:适用于单线程、内存小的机器
并行收集器:适用于多线程并行工作,用户线程等待状态
并发收集器:停顿时间优先—CMS G1

垃圾收集器2个指标(目标):1-吞吐量;2-停顿时间;

???一个对象在创建进入Eden区,然后开始count计数,count>1的对象进入S0区域,如果S0区域满了,GC一下到S1中,from 和 to,两个区域循环复制;当count>15,该对象转入old区;


同学作业: LFan

01 结合Eden、S0、S1和Old区,描述一下一个对象创建的过程
答:新生对象的创建一般是在新生代的Eden区中被分配的(但如果对象太大将在老年代被创建),新生代中Eden区的空间通常比S0和S1的要大,因为新生代中,大部分对象都是朝生夕死的,只有少部分存活,因此默认8:1:1,当Eden区中没有足够的内存空间,将触发一次minor GC,将Eden和S0中存活的对象都复制到S1中(复制算法)并且年龄加1,清空Eden和S0,S0和S1的from to关系轮换。每经过一次Minor GC,存活对象的年龄就会加1,且S0和S1的from to关系轮换,当存活对象达到一定年龄(默认15岁)时,对象会被移动到老年代。当老年代空间不足时,将会触发Major GC,将会采用标记-整理或者标记-清除算法进行垃圾回收。

02 怎样确定一个对象为垃圾?
答:确定一个对象是否为垃圾有两种方式:
a.引用计数,当对象被引用一次时,计数加1,当对象被取消引用时,计数减1;当计数为0时,即表征该对象已为垃圾。但引用计数方式存在一个循环引用的问题,即在A对象中引用了B对象,而在B对象中也同时引用了A对象,如果此时A、B对象都不被其他任何对象引用,而引用计数认为A、B计数均为1不是垃圾,其实实际A、
B都是垃圾。
b.可达性分析,也叫根可达算法,即从根(GC Roots)出发引用关系能不能到达到该对象。GC Root通常有类加载器、java虚拟机栈局部变量表、常量、静态变量、本地方法栈中的标量等,因为这些都能表征“正在使用”,“正在使用”再引用的对象,当然是被用到不是垃圾,层层递推下去。比如,java虚拟机栈的局部变量表做为GC Root,因为当前既然存在局部变量表,那么必存在栈帧,必处在现场正在运行该方法,因此“正在使用”,所引用的对象当然也是在被使用的,由此层层递推下去。

03 常用的垃圾回收算法有哪些?并且有什么优缺点
答:
(1)标记-清除算法
先全盘标记,再清除掉标记为垃圾的对象。通常该算法被用于老年代的垃圾回收,典型的垃圾收集器比如CMS(标记清除)、G1(筛选清除)都有采用该算法,但存在标记清除耗时效率不高、内存空间碎片的缺点。
(2)标记-整理算法
先全盘标记,清除掉标记为垃圾的对象的同时,存活对象会向空的位置移动,以达到内存空间连续的目的。通常该算法被用于老年代的垃圾回收。其优点就是解决了标记-清除算法中内存空间碎片的问题,但还是存在标记清除效率不高的缺点。
(3) 复制算法
复制算法首先将内存空间分为两半(1:1),一块做为使用区,一块做为保留区,当发生GC时,将存活对象连续地复制到保留区中,然后将原使用区一次性清除所有,将保留区转化为新的使用区,将原使用区转化为新的保留区。通常该算法被用于新生代的垃圾回收,典型的模型就是Eden、S0、S1,S0和S1的from和to的关系轮换就是使用区和保留区的关系轮换。其优点就是简单且高效,缺点是浪费了一半的内存空间。
X2

C99

01 结合Eden、S0、S1和Old区,描述一下一个对象创建的过程:
首先放入eden区域,经过一次gc后,对象头中(mark word)中的garbage collect count + 1。随之判定eden区GC次数(年龄)大于1的放入S0 or S1中。
S0 与 S1采用copy算法,一半总是完全空闲的。当幸存者1 or 2区中的对象的年龄超过15时(默认15),将对象放入old区,认为该对象轻易不会被回收。
02 怎样确定一个对象为垃圾?
Count计数:每个对象有一个Count计数器,有人引用+1,为0则可回收。
可达性分析算法:
一般从局部变量表,方法区中的静态引用实体起手进行搜寻。针对于每个实例引用的实例类型字段,继续往内搜寻,类似递归。
直到该实例引用不包含可搜寻字段(递归边界),即停止搜寻,返回上一层。
03 常用的垃圾回收算法有哪些?并且有什么优缺点
引用计数:每个对象有一个Count计数器,有人引用+1,为0则可回收。但是会发生循环依赖。
标记-清除(mark sweep):
思路:
1、GC时,通过可达性分析算法搜寻存活对象标注flag。
2、清除未标记对象
优点:不会造成循环依赖
缺点:耗时 & 空间碎屑。即部分对象被清除,导致连续存储的对象空间出现空隙,如: obj1, null, obj3, null, obj4。
若此时放入一个需要两个节点才能存放住的大对象,虽然空余空间总量是有的,但是因为不连续性,无法存放。
标记-压缩:
思路:基于标记-清除,不过新增了第三步,重新整理为有序存放。剔除空隙空间。
优点:不会产生空间碎屑
缺点:耗时
Copy算法:
思路:GC时,切分两份等量的存储空间,每次只使用其中之一,即总有一边是空闲的。通过可达性分析算法搜寻存活对象标注flag,搜寻完毕后,直接将有效对象copy到另一边。往复如此。
优点:比较标记-压缩,更快。
缺点:空间换时间,总有一半的空间是闲置的。
分代回收:
首先放入eden区域,经过一次gc后,对象头中(mark word)中的garbage collect count + 1。随之判定eden区GC次数(年龄)大于1的放入S0 or S1中。
S0 与 S1采用copy算法,一半总是完全空闲的。当幸存者1 or 2区中的对象的年龄超过15时(默认15),将对象放入old区,认为该对象轻易不会被回收。
且若一个对象的大小超过设定,会直接放到old区。且,若幸存者区容量不够时,会有一个策略去老年代借用(老年代存有有富裕空间的情况下)

04 Garbage Collector的选择:不同的回收器使用不同的回收算法。不同的回收算法又适合不同场景。即根据场景选择回收器。

​ 新生代的回收器(使用都是Copy算法):

​ 1、Serial:单线程的回收器,单核单CPU下最快(单核开启多个线程只会更浪费性能与时间)。收集时必定造成STW(Stop the world),会暂停所有的业务线程。

​ 2、Parallel New / Parallel Scavenge:与Serial类似,不过是多线程回收。依然存有STW问题,但是吞吐量提高了,毕竟多个线程在执行回收。

​ 老年代的回收器:

​ 1、CMS(Concurrent market sweep):并发标记清除。分为四步:初始标记(STW),并发标记(Conccrent),重新标记(STW),并发清除(Conccrent) 相比前二者STW的时长更短。

​ 2、G1:CMS Collector基础上,用户可以手动调整STW时长,以保证高响应低延迟。若超过指定时长后仍未结束,则放弃部分回收进行响应。且可以使用在新生代。

​ 3、Parallel Old:适用于老年代的并行回收器。

​ 4、Serial Old:老年代的单线程回收器。

​ 搭配:

​ 内存小(<100MB),且不要求高并发快速响应:

​ 新生代:Serial
​ 老年代:Serial Old

​ 高并发低延迟:

​ 新生代:G1
​ 老年代:CMS

​ 高吞吐:
​ 新生代:Parallel scavenge
​ 老年代:Parallel Old

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- nryq.cn 版权所有 赣ICP备2024042798号-6

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务