什么时候触发GC
gc 分两组(ScavengeGC或ygc)Minor GC,另一种是FullGC,前者是对年轻代进行回收,后者都是正个堆进行回收(年轻代、老年代和持久代)都会停止应用程序的线程,不过这个过程非常短暂。
1、当eden申请内存申请失败时,触发Minor GC
2、当老年代(Tenured)被写满、持久代(Perm)被写满、System.gc() 被显示调用以及上一次GC之后Heap各域分配策略出现变化时,触发FullGC。
最后来讲一下垃圾回收流程。
1、新建的对象,大部分存储在Eden中
2、当Eden内存不够,就进行Minor GC释放掉不活跃对象;然后将部分活跃对象复制到Survivor中(如Survivor1),同时清空Eden区
3、当Eden区再次满了,将Survivor1中不能清空的对象存放到另一个Survivor中(如Survivor2),同时将Eden区中的不能清空的对象,复制到Survivor1,同时清空Eden区
4、重复多次(默认15次):Survivor中没有被清理的对象就会复制到老年区(Old)
5、当Old达到一定比例,则会触发Major GC释放老年代
6、当Old区满了,则触发一个一次完整的垃圾回收(Full GC)
7、如果内存还是不够,JVM会抛出内存不足,发生oom,内存泄漏。
分代垃圾回收
Minor GC:用于清理新生代(Eden)区域,Eden区满了就会触发一次Minor GC,清理无用对象,将有用对象复制到"Survivor1","Survivor2"区中(这两个区,大小空间相同,同一时刻Survivor1和Survivor2只有一个在用一个为空)。
Major GC:用于清理老年代区域。
Full GC:用于清理新生代,老年代区域,成本较高,会对系统性能产生影响。
GcRoot:
GcRoot是垃圾回收器算法中判断一个对象是否可以回收的一种算法就是对象到达GcRoot的路径是否还有可达,即是否有可引用链,如果有,这表明对象还存在着引用,
如果没有,则表明该对象没有引用,在下一次垃圾回收时就会被回收
GcRoot的种类
1.虚拟机栈:栈帧中的本地变量表引用的对象
2.native方法引用的对象
3.方法区中的静态变量和常量引用的对象
jvm调优
-client——设置JVM使用Client模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或开发调试;在32位环境下直接运行Java程序默认启用该模式。
-server——设置JVM使Server模式,特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境。在具有64位能力的JDK环境下默认启用该模式。
参数说明
-Xms768m:设置JVM初始堆内存为768m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmx768m:设置JVM最大堆内存为768m。
-Xss128k:设置每个线程的栈大小。JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K。应当根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。需要注意的是:当这个值被设置的较大(例如>2MB)时将会在很大程度上降低系统的性能。
-Xmn2g:设置年轻代大小为2G。在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的3/8。
-XX:NewSize=1024m:设置年轻代初始值为1024M。
-XX:MaxNewSize=1024m:设置年轻代最大值为1024M。
-XX:PermSize=256m:设置持久代初始值为256M。
-XX:MaxPermSize=256m:设置持久代最大值为256M。
-XX:NewRatio=4:设置年轻代(包括1个Eden和2个Survivor区)与年老代的比值。表示年轻代比年老代为1:4。
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的比值。表示2个Survivor区(JVM堆内存年轻代中默认有2个大小相等的Survivor区)与1个Eden区的比值为2:4,即1个Survivor区占整个年轻代大小的1/6。 -XX:NewSize=n:设置年轻代大小 -
-XX:MaxTenuringThreshold=7:表示一个对象如果在Survivor区(救助空间)移动了7次还没有被垃圾回收就进入年老代。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代被垃圾回收的概率,减少Full GC的频率,这样做可以在某种程度上提高服务稳定性。
如果想提升jvm的qbs指数时:
1、最大堆和最小堆设置为一致,避免每次垃圾回收完成后JVM重新分配内存(根据服务器内存)
2、设置每个线程的栈大小(根据业务实际情况代码栈不是很深的话(递归))
3、设置对象在年轻代到老年代的频率(jvm年轻代对象标记默认标记次数15进入老年代),减少标记次数
4、设置年轻代和老年代比例
5、设置eden区和2个Survivor的比例
6、这里不涉及收集器,年轻代默认是并行回收
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。这个涉及业务是否计算密集型