java基础知识,垃圾回收机制

对象优先分配到Eden区

/**
 * -XX:+PrintGCDetails 打印GC详情信息
 * -XX:+PrintGC 打印GC信息
 */
public class TestPolicy1 {
   private static final int _1MB = 1024 * 1024;

   public static void testAllocation() {
      byte[] allocation1, allocation2, allocation3, allocation4;
      allocation1 = new byte[2 * _1MB];
      allocation2 = new byte[2 * _1MB];
      allocation3 = new byte[2 * _1MB];
      allocation4 = new byte[4 * _1MB];
   }

   public static void main(String[] args) {
      testAllocation();
   }
}

大对象直接进入老年代

/**
 * -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
 * -XX:PretenureSizeThreshold=3145728  // 设置对象直接进入老年代的阈值。对SerialGC和ParNew起作用
 */
public class TestPolicy2 {
   private static final int _1MB = 1024 * 1024;

   /**
    * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
    * -XX:PretenureSizeThreshold=3145728。默认值是0
    */
   public static void testPretenureSizeThreshold() {
      byte[] allocation;
      // 直接分配在老年代中
      allocation = new byte[4 * _1MB];
   }

   public static void main(String[] args) {
      testPretenureSizeThreshold();
   }
}

长期存活的对象会进入老年代

public class TestPolicy3 {
   private static final int _1MB = 1024 * 1024;

   /**
    * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90
    * -XX:+PrintGCDetails
    * -XX:MaxTenuringThreshold=1
    * -XX:+PrintTenuringDistribution
    * Jdk 1.7.0_46
    */
   public static void testTenuringThreshold() throws InterruptedException {
      byte[] allocation1, allocation2, allocation3;
      allocation1 = new byte[_1MB / 4];
      //什么时候进入老年代取决于XX:MaxTenuringThreshold设置
      allocation2 = new byte[4 * _1MB];
      allocation3 = new byte[4 * _1MB];
      System.out.println("=============");
      allocation3 = null;
      allocation3 = new byte[4 * _1MB];
      System.out.println("=============");
   }

   public static void main(String[] args) throws InterruptedException {
      testTenuringThreshold();
   }
}

动态年龄判断

如果在Survivor空间中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于平均年龄的对象直接进入老年代。

空间担保

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。
如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次Full GC。

关于GC清理

MinorGC用于清理新生代,MajorGC清理老年代。FullGC清理新生代+老年代(方法区)
MinorGC触发条件:当新生代无法给新对象分配空间时。如:Eden区满了。
MajorGC触发条件:老年代没有空间。经历一次MinorGC
FullGC触发条件:

  • System.gc
  • 老年代空间不足
  • 方法区空间不足
  • 经过MinorGC后,进行的对象大小大于老年代的可用空间。Eden+From到To复制的时候,对象的大小大于To区域大小,当把对象转到老年,这个时候老年代的空间小于对象大小。

GC信息解读

[GC (Allocation Failure) [DefNew: 6518K->898K(9216K), 0.0038707 secs] 6518K->4994K(19456K), 0.0042538 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

GC (Allocation Failure) GC的类型,括号里面是GC产生的原因。
DefNew 垃圾回收期的名称
6518K->898K(9216K) 6518K代表GC之前大小,898K代表GC之后的大小。9216K总的大小。
0.0038707 secs GC暂停的时间。
6518K->4994K(19456K) 整个区域的情况。
[Times: user=0.00 sys=0.00, real=0.00 secs]
user 执行GC期间线程消耗的总CPU时间
sys 操作系统调用或者等待系统事件等待的时间
real 应用程序停止的时间。
FullGC(xxxxxxx)

  • FullGC(Metadata GC Threashold) 元空间不足触发了GC
  • FullGC(System.gc()) 手动调用触发GC
  • FullGC(Ergonomics)

附录:JVM内存管理参数

DisableExplicitGC 默认关闭 忽略来自System.gc()方法触发的垃圾收集
ExplicitGCInvokesConcurrent 默认关闭 当收到System.gc()方法提交的来机收集申请时,使用CMS收集器进行收集
UseSerialGC Client模式的虚拟机默认开启,其他模式关闭 虚拟机运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old的收集器组合进行内存回收
UseParNewGC 默认关闭 打开此开关后,使用ParNew + Serial Old的收集器组合进行内存回收
UseConcMarkSweepGC 默认关闭 打开此开关后,使用ParNew + CMS + Serial Old的收集器组合进行内存回收.如果CMS收集器出现Concurrent Mode Failure,则Serial Old收集器将作为后备收集器
UseParallelGC Server模式的虚拟机默认开启,其他模式关闭 虚拟机运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge + Serial Old的收集器组合进行内存回收
UseParallelOldGC 默认关闭 打开此开关后,使用Parallel Scavenge + Parallel Old的收集器组合进行内存回收
SurvivorRatio 默认为8 新生代中Eden区域与Survivor区域的容量比
PretenureSizeThreshold 无默认值 直接晋升到老年代的对象大小,设置这个参数后,大于这个参数的对象将直接在老年代分配
MaxTenuringThreshold 默认值为15 晋升到老年代的对象年龄,每个对象在坚持过一次Minor GC之后,年龄就+1,当超过这个参数值时就进入老年代
UseAdaptiveSizePolicy 默认开启 动态调整java堆中各个区域的大小及进入老年代的年龄
HandlePromotionFailure jdk1.5及以前是默认关闭,jdk1.6默认开启 是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden和Survivor区的所有对象都存活的极端情况
ParallelGCThreads 少于或等于8个CPU时默认值为CPU数量值,多于8个CPU时比CPU数量值小 设置并行GC时进行内存回收的线程数
GCTimeRatio 默认值99 GC时间占总时间的比率.仅在使用Parallel Scavenge收集器时生效
MaxGCPauseMills 无默认值 设置GC最大停顿时间.仅在使用Parallel Scavenge收集器时生效
CMSInitiatingOccupancyFraction 默认值68 设置CMS收集器在老年代空间被使用多少后触发垃圾收集
UseCMSCompactAtFullCollection 默认开启 设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片整理
CMSFullGCsBeforeCompaction 无默认值 设置CMS收集器在进行若干次垃圾收集后再启动一次内存碎片整理
ScavengeBeforeFullGC 默认开启 在Full GC发生之前触发一次Minor GC
UseGCOverheadLimit 默认开启 禁止GC过程无限制的执行,如果过于频繁,就直接发生OutOfMemory
UseTLAB Server模式默认开启 优先在本地线程缓冲区中分配对象,避免分配内存时的锁定过程
MaxHeapFreeRatio 默认值70 当Xmx值比Xms值大时,堆可以动态收缩和扩展,这个参数控制当堆空闲大于指定比率时自动收缩
MinHeapFreeRatio 默认值40 当Xmx值比Xms值大时,堆可以动态收缩和扩展,这个参数控制当堆空闲小于指定比率时自动收缩
MaxPermSize 大部分情况下默认值是64MB 永久代的最大值
即时编译参数
CompileThreshold Client模式下默认值1500,Server模式下默认值10000 触发即时编译的阈值
OnStackReplacePercentage Client模式下默认值933,Server模式下140 OSR比率,它是OSR即时编译阈值计算公司的一个参数,用于代替BackEdgeThreshold参数控制回边计数器的实际溢出阈值
ReservedCodeCacheSize 大部分情况下默认值32MB 即时编译器编译的代码缓存使得最大值
类型加载参数
UseSplitVerifier 默认开启 使用依赖StackMapTable信息的类型检查代替数据流分析,以加快字节码校验速度
FailOverToOldVerifier 默认开启 当类型校验失败时,是否允许回到老的类型推到校验方式进行校验,如果开启则允许
RelaxAccessControlCheck 默认开启 在校验阶段放松对类型访问性的限制
多线程相关参数
UseSpinning Jdk1.6默认开启,Jdk1.5默认关闭 开启自旋锁以免线程频繁的挂起和唤醒
PreBolckSpin 默认值10 使用自旋锁时默认的自旋次数
UseThreadPriorities 默认开启 使用本地线程优先级
UseBiasedLocking 默认开启 是否使用偏向锁,如果开启则使用
UseFastAccessorMethods 默认开启 当频繁反射执行某个方法时,生成字节码来加快反射的执行速度
性能参数
AggressiveOpts Jdk1.6默认开启,Jdk1.5默认关闭 使用激进的优化特征,这些特征一般是具备正面和负面双重影响的,需要根据具体应用特点分析才能判定是否对性能有好处
UseLargePage 默认开启 如果可能,使用大内存分页,这项特性需要操作系统的支持
LargePageSizeInBytes 默认值4MB 使用指定大小的内存分页,这项特性需要操作系统的支持
StringCache 默认开启 是否使用字符串缓存,开启则使用
调试参数
HeapDumpOnOutOfMemoryError 默认关闭 在发生内存溢出异常时是否生成堆转储快照,关闭则不生成
OnOutOfMemoryError 无默认值 当虚拟机抛出内存溢出异常时,执行指令的命令
OnError 无默认值 当虚拟机抛出ERROR异常时,执行指令的命令
PrintClassHistogram 默认关闭 使用[ctrl]-[break]快捷键输出类统计状态,相当于jmap-histo的功能
PrintConcurrentLocks 默认关闭 打印J.U.C中的状态
PrintCommandLineFlags 默认关闭 打印启动虚拟机时输入的非稳定参数
PrintFlagsFinal ---- 显示所有可设置的参数及它们的值(***从JDK 6 update 21开始才可以用)
PrintFlagsInitial ---- 显示在处理参数之前所有可设置的参数及它们的值,然后直接退出程序
PrintCompilation 默认关闭 打印方法即时编译信息
PrintGC 默认关闭 打印GC信息
PrintGCDetails 默认关闭 打印GC的详细信息
PrintGCTimeStamps 默认关闭 打印GC停顿耗时
PrintTenuringDistribution 默认关闭 打印GC后新生代各个年龄对象的大小
TraceClassLoading 默认关闭 打印类加载信息
TraceClassUnloading 默认关闭 打印类卸载信息
PrintInlining 默认关闭 打印方法内联信息
PrintCFGToFile 默认关闭 将CFG图信息输出到文件,只有DEBUG版虚拟机才支持此参数
PrintIdealGraphFile 默认关闭 将Ideal图信息输出到文件,只有DEBUG版虚拟机才支持此参数
UnlockDiagnosticVMOptions 默认关闭 让虚拟机进入诊断模式,一些参数(如PrintAssembly)需要在诊断模式中才能使用
PrintAssembly 默认关闭 打印即时编译后的二进制信息
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容