前言: gc回收是一门一个比较深奥且广泛的知识点,并不是三言两语能够理解透彻的,网络上也有很多相关文章,本篇仅仅是以入门的角度去揭开gc的面纱,此文章仅代表鄙人的总结和理解,如有错漏,欢迎指正...
一、什么是GC?

在新生代的时候存的东西过多放不下的时候,就会发生一次GC。
大对象和长期存活的对象将会放入老年区,如果老年区空间不够了再对老年区进行GC。
永久代是保存那些java类和加载器本身活跃的部分。
二、GC什么时候回收?
JVM中使用了一种可达性分析算法来判定哪些对象是可以被回收的。
1.对象没有引用
2.作用域发生未捕获异常
3.程序在作用域正常执行完毕
4.程序执行了System.exit()
总之记住一句话,只要你的对象被类的静态变量给引用了,就不会回收他。因为静态变量初始化就存在了。一直都会存在的。 被GC roots所直接引用的对象。只要是强引用关系,那么垃圾回收器是绝对不会回收这个对象的。
三、如何防止被gc回收?
当对象被回收的时候,调用finalize方法,重新将GC Roots的变量引用指向自己,那么就不会被回收了。
作用:
GC是垃圾收集的意思,垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存
四、新生代和老年代垃圾回收的细节
JVM会将堆内存分为两个区域:
新生代:
对象在被实例化之后,都是属于新生代,特点是很快就会被回收,所以需要使用一种垃圾回收算法,当新生代躲过10次gc回收,就认为他是老人然后转移到老年代去。
老年代:
一些会长期存活的对象和超大对象直接不经过新生代,直接进入老年代
永久代:
存放一些类的信息,比如生成的生成的.class,jsp页面(jsp页面过多会导致永久代内存溢出)
一般情况下,我们对于jvm调优都是对新生代和老年代进行调优。一般而言永久代保持默认配置就可以了。
动态年龄判断机制:
垃圾回收器的算法来讲,就是复制算法
我们一般会将新生代分为三个区域,一个Eden,两个Survivor。比例8:1:1
生成的对象默认在eden区域。当发生一次Minor GC后,会将存活的对象复制到其中一个Survivor区域。当下一次GC后又会将存活的对象复制到另一块Survivor。这么做的好处是减少内存碎片。
当我们发生一次GC后,将存活对象放到其中一块survivor区域。发现其中的1岁,2岁,3岁的对象年龄加起来内存超过survivor区域的一半,就会把4岁以及4岁以上的对想转移到老年代。
gc后Survivor区域放不下:
这个没办法,GC后都还存放不下一般来说要不是访问量激增,要么就是优化的不到位,所以只好将这写对象转移到老年代。
空间担保机制:
在发生minor gc之前,虚拟机会检测 : 老年代最大可用的连续空间 > 新生代all对象总空间?
1、满足,minor gc是安全的,可以进行minor gc。
2、不满足,虚拟机查看HandlePromotionFailure参数:
(1)为true,允许担保失败,会继续检测老年代最大可用的连续空间>历次晋升到老年代对象的平均大小。若大于,将尝试进行一次minor gc,若失败,则重新进行一次full gc。
(2)为false,则不允许冒险,要进行full gc(对老年代进行gc)。
参考博客:
新生代和老年代垃圾回收的细节
结语:以往都是看别人的博客进行学习技术,其中不乏有精华博客也有吊儿郎当的CV大法文章,所以决定将自己所学所用所整理的知识分享给大家,主要还是想为了后浪们少走些弯路,多些正能量的博客,如有错漏,欢迎指正,仅希望大家能在我的博客中学到知识,解决到问题,那么就足够了。谢谢大家!(转载请注明原文出处)