1、什么是JVM垃圾回收
java程序员在开发过程中不用考虑对象的销毁,正是由于jvm的垃圾回收器,从而确保了在不断有请求到达,不断创建对象,不断对外提供服务的java程序能够一直正常运行;
垃圾回收的主要区域为堆和方法区,都是所有线程共享的内存区域;堆被划分为新生代和老年代,其中新生代分为Eden区和Survivor区,Survivor区又分为FromSpace 和ToSpace;方法区被称为持久代;
垃圾回收的对象为堆中的对象实例、方法区的类信息和常量信息等;
鉴别垃圾的算法通过GC ROOT的可达性分析是变出需要回收的对象,主要包括:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象;
- 方法区中静态变量引用的对象;
- 方法区中常量引用的对象;
- 本地方法栈(即一般说的 Native 方法)中JNI引用的对象;
其中引用的类型又分为以下4类:
强引用:指在代码中普遍存在的,类似 Object obj = new Object(); 这类的引用,只有强引用还存在,GC就永远不会收集被引用的对象;
软引用:指一些还有用但并非必须的对象。直到内存空间不够时(抛出OutOfMemoryError之前),才会被垃圾回收。采用SoftReference类来实现软引用;
弱引用:用来描述非必须对象。当垃圾收集器工作时就会回收掉此类对象。采用WeakReference类来实现弱引用;
虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响, 唯一目的就是能在这个对象被回收时收到一个系统通知, 采用PhantomRenference类实现;
垃圾回收算法:
标记/清除算法:释放空间不连续容易导致内存碎片;
复制算法:耗费空间,新生代的垃圾回收算法;
标记/整理算法:在标记/清楚算法的基础上进行整理得到连续内存,老年代的垃圾回收算法;
垃圾回收的一些机制:
- 对象会优先在新生代的Eden区中分配,当Eden区没有足够空间进行分配时,虚拟机会发起一次
Minor GC,仍然
存活的对象,将会送到Survivor
的From区,若From区空间不足则直接进入Old区(大对象直接进入老年代); - Survivor区相当于是Eden区和Old区的一个缓冲,
Minor GC后,
Eden区存活的对象被放到From区,由于复制算法,此时From区和To区逻辑互换,下一次Minor GC后,
Eden区存活的对象以及To区原有的对象都被放到From区,From区和To区逻辑再次互换,以此类推; - 对象从To区到From区的次数,也就是该对象存在过程中发生
Minor GC的次数称之为他们的年龄,当年龄达到16后,仍然存活的对象会被放到
Old区(长期存活的对象将进入老年代); - 当发生
Minor GC后,
Eden区存活的对象以及To区原有的对象都被放到From区,此时From区空间不足且没有年龄达到16的对象时,较大年龄的对象进入Old区(动态对象年龄判定); - 在进行MinorGC(新生代的GC)的时候,会判断要进入Old区对象的大小,是否大于Old 区剩余空间大小,如果大于就会发生Full GC;
- 持久代的方法区,如类的实例对象全部被GC了,同时它的类加载器也被GC掉了,此时就会触发持久代中该实例对象的类信息和常量信息GC;
2、常见的垃圾回收器
新生代收集器:Serial、ParNew、Parallel Scavenge;
老年代收集器:CMS、Serial Old、Parallel Old;
整堆收集器: G1;
3、JVM调优参数