总结:垃圾回收
(1)判断的标准:
GC Root:
a.被Java虚拟机栈直接或者间接引用的对象
b.被本地方法栈直接或者间接引用的对象
c.方法区的变量或者常量直接引用的对象
(2)处理的算法:
a.标记-清理算法:在对象后面标记一下,把含有标记的对象给它删除掉。缺点:会产生内存碎片,例如分别删除了2个1k的内存(现在有2个1k的内存是空着了),这时new了1个2k的内存出来,这个时候不能把这个2k的内存放在2个1k的内存里面,而且也不能被拆分,所以这2个1k的内存就不能被合理的利用起来了。
b.标记-整理算法:如果下一个内存是空的,就把空的内存往前面顶,这样就会减少内存的碎片。缺点:代价比较大,因为所有的内存都要往前面移动
c.复制算法:将内存一分为二(假设是a内存,b内存),在a内存中标记要删除的内存,然后在b内存中,将a内存中没有标记的内存一个个移过来,紧凑的拍着,避免了内存碎片和代价大的问题。缺点:要有2倍的内存
d.实际的GC算法:
Ⅰ、将内存进行了划分,一部分是年轻代(Young区),还有一部分是老年代(Old区)
Ⅱ、年轻代也进行了划分,分别是1个Eden区和2个Survivor区;Old区就是整个的一块
Ⅲ、new的对象产生在Eden区,当Eden区快满的时候,就会触发GC,这个GC是在Young区的,所以也叫Young GC,Young GC采用的是复制算法,把在Eden区需要删除的打上一个标记,不需要删除的放在Survivor区(S0或者S1均可,内存大小 S0:S0:E区=1:1:8)。为什么要2块Survivor区?因为这个S区是交替工作的,在E区打完标记后,不需要删除的被放到S0区,然后把E区+S1区一起删除,等下一次满的时候,将不需要删除的被放到S1区,然后把E区+S0区一起删除...如此往复的工作,比将内存一分为二的效率要高一些的(主要是针对 对象的朝生夕死的特点去设计的)
Ⅳ、Old区:在每一次的Young GC的时候,它的年龄都会加1,直到年龄到达了15岁(7是初始值,岁数是个动态变化的值,在每次gc的时候都会重新计算,和s区存活率[默认50%]等其它参数有关),它就不在Survivor区里面进行复制了,而是直接将不需要删除的对象放到Old区里面,因为之前的Young GC都没去掉,说明可能要过很久才能去掉;除了存了年龄大于等于15岁的,还存了大的对象(如:1个1千万大小的int数组),Old区满的时候也会触发GC,Old GC一般也会伴随着Young GC,所以也叫做Full GC,Full GC会引起Stop-The-World,整个Java程序直接暂停,来全力的进行垃圾回收,
Ⅴ、垃圾回收主要使用的是标记-清理算法或者是标记-整理算法
Ⅵ、标记-清理算法,标记-整理算法 主要是在Old区里面的;复制算法主要用在Young区
e.比较著名的垃圾收集器:
Ⅰ、年轻代的 ParNew(复制算法) ; 老年代的 CMS (标记-清理算法)
Ⅱ、最新的采用了G1垃圾收集器
垃圾回收总结
最新推荐文章于 2022-06-23 19:55:12 发布