1.对象已死?
1.引用计数算法2.可达性分析算法
2.引用
1.强引用2.软引用
3.弱引用
4.虚引用
作用:在这个对象被回收时,收到一个系统通知
3.Finalize
一个对象死亡的过程发现没有和GC Roots相连接->被标记一个,并检测,是否有必要执行Finalize方法->Yes的话被放入F-Queue中
->稍后GC对 F-Queue队列进行标记->对象如果在finalize中拯救了自己,他将被移出即将回收队列
这个方法不同于C++析构函数,不建议使用
4.垃圾收集算法
1.标记-清除算法两个不足:效率问题,标记与清除两个功能效率都不高;空间问题,会产生大量碎片
2.复制算法
简单,高效,代价是牺牲一半的内存
适合新生代
3.标记-整理算法
先进行标记,然后让存活下来的向一边移动,然后清理掉边界外的内存
4.分代收集算法
根据对象存活周期不同,将内存划分为几块,新生代使用2复制算法。老年代使用标记清除或标记整理算法
5.HotSpot算法实现-虚拟机如何发起内存回收
1.枚举根节点
枚举根节点时必须保证分析过程中对象的引用关系没有变化。枚举根节点时,虚拟机一定会停顿。
主流虚拟机使用精确式GC,HotSpot中使用OopMap的数据结构来定位对象引用。
2.安全点
Hotspot会在特定位置记录了对象引用到OopMap,这个位置就是安全点。
安全点选定问题:
如何让所有线程都跑到“安全点停下来那?
1.抢占式中断
先把所有线程都中断,然后让没有在安全点的,恢复线程,让他跑到安全点(这种方法几乎没有人使用了)
2.主动式中断”
不直接操作线程,仅设置一个标志,这个标志与安全点重合,执行到安全点就完成线程中断
3.安全区域
6.HotSpot算法实现-垃圾收集器
1.Serial收集器
2.PerNew收集器
PeriNew 是Serial的多线程版本,一个并行的多线程收集器。是很多在Server下面首选的新生代收集器,与性能无关的原因是:目前只有他能与CMS收集器配合工作。
3.Parallel Scavenge收集器
特点:
1,吞吐量优先收集器
2,于PeiNew区别是,这个收集器采用自适应调节策略
这个收集器的目的是达到一个可控制的吞吐量。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
参数详解:
1,-XX:MaxGCPauseMillis
设置内存回收不超过的时间,GC停顿时间缩短是以牺牲性能和新生代空间来保证的。
2,-XX:GCTimeRadtio
设置垃圾收集时间所占比重。(0<n<100)
3.-XX:UserAdaptiveSizePolicy
只需设置好基本的内存数据,然后剩下的交给虚拟机自动完成
4,Serial Old收集器
5,Parallel Old收集器
Parallel Scavenge老年化版本,
在注重吞吐量和CPU资源敏感的地方使用 Parallel Scavenge 和Parallel Old 组合
6,CMS收集器
7,G1收集器
XX:+<option> 启用选项-XX:-<option> 不启用选项-XX:<option>=<number>-XX:<option>=<string>
附录:参数 描述
-XX:+UseSerialGC | Jvm运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old的收集器组合进行内存回收 |
-XX:+UseParNewGC | 打开此开关后,使用ParNew + Serial Old的收集器进行垃圾回收 |
-XX:+UseConcMarkSweepGC | 使用ParNew + CMS + Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现“Concurrent Mode Failure”失败后的后备收集器使用。 |
-XX:+UseParallelGC | Jvm运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge + Serial Old的收集器组合进行回收 |
-XX:+UseParallelOldGC | 使用Parallel Scavenge + Parallel Old的收集器组合进行回收 |
-XX:SurvivorRatio | 新生代中Eden区域与Survivor区域的容量比值,默认为8,代表Eden:Subrvivor = 8:1 |
-XX:PretenureSizeThreshold | 直接晋升到老年代对象的大小,设置这个参数后,大于这个参数的对象将直接在老年代分配 |
-XX:MaxTenuringThreshold | 晋升到老年代的对象年龄,每次Minor GC之后,年龄就加1,当超过这个参数的值时进入老年代 |
-XX:UseAdaptiveSizePolicy | 动态调整java堆中各个区域的大小以及进入老年代的年龄 |
-XX:+HandlePromotionFailure | 是否允许新生代收集担保,进行一次minor gc后, 另一块Survivor空间不足时,将直接会在老年代中保留 |
-XX:ParallelGCThreads | 设置并行GC进行内存回收的线程数 |
-XX:GCTimeRatio | GC时间占总时间的比列,默认值为99,即允许1%的GC时间,仅在使用Parallel Scavenge 收集器时有效 |
-XX:MaxGCPauseMillis | 设置GC的最大停顿时间,在Parallel Scavenge 收集器下有效 |
-XX:CMSInitiatingOccupancyFraction | 设置CMS收集器在老年代空间被使用多少后出发垃圾收集,默认值为68%,仅在CMS收集器时有效,-XX:CMSInitiatingOccupancyFraction=70 |
-XX:+UseCMSCompactAtFullCollection | 由于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效 |
-XX:+CMSFullGCBeforeCompaction | 设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用 |
-XX:+UseFastAccessorMethods | 原始类型优化 |
-XX:+DisableExplicitGC | 是否关闭手动System.gc |
-XX:+CMSParallelRemarkEnabled | 降低标记停顿 |
-XX:LargePageSizeInBytes | 内存页的大小不可设置过大,会影响Perm的大小,-XX:LargePageSizeInBytes=128m |
Client、Server模式默认GC
新生代GC方式老年代和持久 代GC方式
Client | Serial 串行GC | Serial Old 串行GC |
Server | Parallel Scavenge 并行回收GC | Parallel Old 并行GC |
Sun/oracle JDK GC组合方式
新生代GC方式老年代和持久 代GC方式
-XX:+UseSerialGC | Serial 串行GC | Serial Old 串行GC |
-XX:+UseParallelGC | Parallel Scavenge 并行回收GC | Parallel Old 并行GC |
-XX:+UseConcMarkSweepGC | ParNew 并行GC | CMS 并发GC 当出现“Concurrent Mode Failure”时 采用Serial Old 串行GC |
-XX:+UseParNewGC | ParNew 并行GC | Serial Old 串行GC |
-XX:+UseParallelOldGC | Parallel Scavenge 并行回收GC | Parallel Old 并行GC |
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC | Serial 串行GC | CMS 并发GC 当出现“Concurrent Mode Failure”时 采用Serial Old 串行GC |