【JVM知识汇总-1】JVM内存模型【JVM知识汇总-2】HotSpot虚拟机对象【JVM知识汇总-3】垃圾回收策略与算法【JVM知识汇总-4]HotSpot垃圾收集器[JVM知识汇总-5]内存分配与回收策略[JVM知识汇总-6]JVM性能调优[JVM知识汇总-7]Class文件结构[JVM知识汇总-8]类加载时序【JVM知识总结-9】类加载过程【JVM知识总结-10】类加载器对象的内存分配是在堆上分配的(也有可能在JIT编译后拆解成标量类型,间接在Stack分配),对象主要分配在新生代的Eden区,少数情况下可能会直接分配在老年代。分配规则不固定,取决于当前使用的垃圾收集器组合和相关参数配置。下面列举一些最常见的内存分配规则,供大家学习。对象首先分配在Eden多数情况下,对象分配在新生代的Eden区。当Eden区没有足够的空间分配时,虚拟机会发起一次MinorGC。MinorGCvsMajorGC/FullGC:MinorGC:回收新生代(包括Eden区和Survivor区),因为大多数Java对象都具有永恒的特性,所以MinorGC非常频繁,回收速度一般较快。MajorGC/FullGC:回收老年代,出现MajorGC,往往伴随至少一次MinorGC,但这不是绝对的。MajorGC的速度一般比MinorGC慢10倍以上。在JVM规范中,MajorGC和FullGC都没有正面的定义,所以有人简单的认为MajorGC是清理老年代,而FullGC是清理整个内存堆。大对象直接去老年代大对象是指需要大量连续内存空间的Java对象,比如很长的字符串或者数据。Eden区能存放大对象的概率比较小,分配保证的概率比较高,而且分配保证涉及到大量的副本,会造成效率低下。虚拟机提供了一个-XX:PretenureSizeThreshold参数,让大于这个设置值的对象直接分配到老年代。这样做的目的是为了避免在Eden区和两个Survivor区进行大量的内存拷贝。(记住,新生代使用复制算法进行垃圾回收)长寿命的对象会进入老年代。JVM为每个对象定义一个对象年龄计数器。当新生代发生MinorGC时,存活对象的年龄+1。当年龄超过一定值时,所有超过该值的对象都被转移到老年代。使用-XXMaxTenuringTreshold设置新生代的最大年龄,只要新生代对象超过这个参数,就会被转移到老年代。动态确定对象年龄如果当前Survivor新生代中所有同龄对象的大小之和大于Survivor空间的一半,则年龄>=该年龄的对象可以直接进入老年代,无需等待MaxTenuringThreshold中要求的年龄。空间分配保证JDK6Update24之前的规则如下:在MinorGC发生之前,虚拟机首先检查老年代的最大可用连续空间是否大于新生代的所有对象空间。如果这个条件为真,MinorGC可以保证安全;如果不成立,虚拟机会检查HandlePromotionFailure值是否设置为允许保证失败。如果是,则继续检查老年代最大可用连续空间是否大于晋升到老年代的对象的平均大小。如果较大,它会提出一个MinorGC,虽然这个MinorGC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那么此时应该进行FullGC。JDK6Update24之后的规则变成:只要老年代的连续空间大于新生代中对象的总和或者两次提升的平均大小,就会进行MinorGC,否则进行FullGC。oldgeneration会通过清除oldgeneration中过时数据的Freespace来扩充newgeneration。这个过程就是抵押品的分配。总结一下哪些情况可能会触发JVM进行FullGC。当调用System.gc()方法时,建议JVM在调用该方法时进行FullGC。注意,这只是一个建议,并不能确定,但??在很多情况下会触发FullGC,从而增加FullGC的频率。通常我们只需要让虚拟机自己管理内存,我们可以通过-XX:+DisableExplicitGC来禁止调用System.gc()。Insufficientspaceintheoldgeneration老年代空间不足会触发FullGC操作。如果运行后空间仍然不足,会抛出如下错误:java.lang.OutOfMemoryError:JavaheapspaceThepermanentgenerationspaceisinsufficientintheruntimedataareaintheJVMspecificationThemethodareaintheJVMspecification,alsoHotSpot虚拟机中称为PermanetGeneration,存储了一些类信息、常量、静态变量等数据,永久代可能已经满了,就会触发FullGC。如果FullGC后仍然无法回收,那么JVM会抛出如下错误信息:java.lang.OutOfMemoryError:promotionfailedandconcurrentmodefailurepromotionfailedduringPermGenspaceCMSGC,也就是上面说的保证失败,并发模式failure是在CMSGC过程执行过程中,有对象要放入老年代,老年代空间不足造成的。根据MinorGC的统计,老年代的平均大小大于老年代的剩余空间。
