上一章节主要是Java内存分区与内存溢出的基础讲解,着篇主要讲解一些策略与GC等等,我的知识更新也是按照《深入理解Java虚拟机》来进行的,不足之处多鞭打。
根据内存模型,虚拟机栈、本地方法、程序计数器都是线程私有的,在创建之初栈深度等已经确定,方法结束的时候就回收。所以主要讨论的是Java堆与方法区(虽然JDK8没有方法了)。
Java堆中注意存储对象,我们关心的结果是对象是否已经“死去”。如下图JVM是通过是否可达Reachability Analysis分析。
提示:标记两次就“死亡”。

Java 语言中,GC Root的对象有以下几种:
虚拟机栈中(帧栈中的本地变量表)引用的对象 方法区(1.8堆)中类静态属性引用的对象 方法区(1.8堆)常量引用的对象 方法的native(1.8本地内存)引用的对象
引用对象定义:
强引用Strong Reference,主要存在就不会回收对象。
软引用Soft Reference,一些有非必需的对象。内存溢之前进行软引用回收。
弱引用weekReference是非必需对象,比软引用更弱。下一次内存回收,回收掉弱引用。
虚引用PhantomReference,设置虚引用就是为了得到一个回收通知。
标记需要回收的空间。缺点:是空间不连续,效率也很低下。
将内存分为两块,每次只使用其中一块,清理复制到另一块内存,一般采用这种算法(新生代对象%98“朝生夕死”)。缺点:内存变小
内存划分为Eden空间(大80%)、Sruvivor空间2块(小10%)。模式比例8:1;每次新生代为90%。
所有存活对象向一端移动,清理另一端。
1、记录一下内存偏移量进入OopMap,记录点不能是全部的全局性引用、执行上下文,应该是一些safepoiont ,这个安全点主要是方法调用、循环跳转、异常跳转等。
2、虚拟机采用voluntary suspension 主动式中断,主动轮询到安全点,主动挂起进行枚举Gc root。
3、safe region 安全区域是安全点的扩展,离开安全区域进行枚举Gc Root。
1、“[GC” 与 “[Full GC”为这次垃圾回收的停顿类型,如果有Full表示发送了“stop-the-world”
2、[GC (System.gc())为调用了System.gc()
3、接下来表示垃圾收集器“[DefNew”=“Default New Generation”----》用的是serial收集器
"[Parnew"="Paraller New Genneration"---》用的是Parnew收集器
“[PsYoungGen”==》用的 是Parallel Scavenge 收集器
3.1 紧接着的”9339K->800K(76288L)“=="GC前内存使用容量->GC后内存使用容量(该内存区域总容量)",
4、方括号后面”9339->808K(251392)“=="GC前Java堆使用容量->GC后Java堆使用容量(Java堆总容量)"
5、”0.0014161“==”该区域GC所占用的时间,单位为秒“
6、"[Times: user=0.00 sys=0.00, real=0.00 secs]"=="用户消耗的CPU时间,内核消耗的CPU时间,真正从头到尾的时间"
参 数
描 述
UseSerialGC
虚拟机运行在Client 模式下的默认值,打开此开关后,使用Serial +Serial Old 的收集器组合进行内存回收
UseParNewGC
打开此开关后,使用ParNew + Serial Old 的收集器组合进行内存回收
UseConcMarkSweepGC
打开此开关后,使用ParNew + CMS + Serial Old 的收集器组合进行内存
回收。Serial Old 收集器将作为CMS 收集器出现Concurrent Mode Failure失败后的后备收集器使用
UseParallelGC
虚拟机运行在Server 模式下的默认值,打开此开关后,使用Parallel
Scavenge + Serial Old(PS MarkSweep)的收集器组合进行内存回收
UseParallelOldGC
打开此开关后,使用Parallel Scavenge + Parallel Old 的收集器组合进行内存回收
SurvivorRatio
新生代中Eden 区域与Survivor 区域的容量比值, 默认为8, 代表
Eden :Survivor=8∶1
PretenureSizeThreshold
直接晋升到老年代的对象大小,设置这个参数后,大于这个参数的对象
将直接在老年代分配
MaxTenuringThreshold
晋升到老年代的对象年龄。每个对象在坚持过一次Minor GC 之后,年
龄就加1,当超过这个参数值时就进入老年代
UseAdaptiveSizePolicy
动态调整Java 堆中各个区域的大小以及进入老年代的年龄
HandlePromotionFailure
是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个
Eden 和Survivor 区的所有对象都存活的极端情况
ParallelGCThreads
设置并行GC 时进行内存回收的线程数
GCTimeRatio
GC 时间占总时间的比率,默认值为99,即允许1% 的GC 时间。仅在
实例代码:
GC信息:
如果对象在Eden出生到一次Minor GC新生代GC之后仍然存活,并且在Survivor中容纳,移到Survivor,这个时候年龄1岁,默认阀值为15岁,就会移动到老年代。
示例代码:
GC结果 :XX:MaxTenuringThreshold=0
GC结果 :XX:MaxTenuringThreshold=15
相同年龄对象内存之和大于Survivor的一半,年龄大于或者等于该年龄的对象,直接进入老年代。
上面代码蒋年龄限制设置1-15之间,你会发现,对象直接进入老年代。
1.6之后,老年代的连续空间大于新生代的对象的总大小,或者历次晋升的平均大小,进行Minor GC ,否则full GC。意思就是老年代大于新生代或进行一次Minor GC。
主要讲解垃圾回收器的特点和运作原理,验证了一些虚拟机 分配原则。