南宁霸屏网站开发,创意网,注册公司如何提供注册地址,抖音关键词搜索指数自动内存管理
解决两个问题
自动给对象分配内存
对象一般堆上分配#xff08;而实际上也有可能经过即时编译后被拆散为标量类型并间接地在栈上分配#xff09;
新生对象通常会分配在新生代#xff0c;少数情况下#xff08;例如对象大小超过一定阈值#xff09;也可能…自动内存管理
解决两个问题
自动给对象分配内存
对象一般堆上分配而实际上也有可能经过即时编译后被拆散为标量类型并间接地在栈上分配
新生对象通常会分配在新生代少数情况下例如对象大小超过一定阈值也可能会直接分配在老年代
实际对象分配的规则并不是固定的具体取决于虚拟机使用的是哪一种垃圾收集器以及虚拟机中与内存相关参数的设定
自动回收分配给对象的内存垃圾收集器做的事
对象优先在Eden分配
大多数情况下对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时虚拟机将发起一次Minor GC。
-XX:PrintGCDetails收集器日志参数告诉虚拟机在发生垃圾收集行为时打印内存回收日志并且在进程退出的时候输出当前的内存各区域分配情况。 参数含义
-Xms20M初始 -Xmx20M最大堆内存固定20m
-Xmn10M10MB分配给新生代剩下的10MB分配给老年代
-XX:SurvivorRatio8新生代中Eden区与一个Survivor区的空间比例是8:1
代码
public class AllocationTest {private static final int _1MB 1024 * 1024;public static void main(String[] args) {byte[] a1, a2, a3, a4;a1 new byte[2 * _1MB];a2 new byte[2 * _1MB];a3 new byte[2 * _1MB];a4 new byte[4 * _1MB]; // 出现一次Minor GC}
}控制台打印 上述老年代占用4M跟下一节阈值默认配置有关。
Minor GC、Major GC以及Full GC因为不同垃圾收集器以及不同JDK版本触发条件都不尽相同
Minor GC新生代垃圾收集
Major GC老年代垃圾收集
Full GC全堆垃圾收集
思路基本都是内存不够用了进行垃圾收集
大对象直接进入老年代
大对象指需要大量连续内存空间的Java对象最典型的大对象便是那种很长的字符串或者元素数量很庞大的数组
Java虚拟机中要避免大对象的原因
分配空间时容易导致内存明明还有不少空间时就提前触发垃圾收集以获取足够的连续空间才能安置好大对象而当复制对象时大对象意味着高额的内存复制开销。
-XX:PretenureSizeThreshold指定大于该设置值的对象直接在老年代分配默认值为3145728字节即3M
【-XX:PretenureSizeThreshold3145728】超过3MB的对象都会直接在老年代进行分配。
-XX:PretenureSizeThreshold参数仅在使用Parallel Scavenge并行年轻代和Parallel Old并行老年代【JDK8默认组合】收集器组合时以及Serial和ParNew两款新生代收集器有效。
长期存活的对象将进入老年代
HotSpot虚拟机中多数收集器都采用了分代收集来管理堆内存那内存回收时就必须能决策哪些存活对象应当放在新生代哪些存活对象放在老年代中。
虚拟机给每个对象定义了一个对象年龄Age计数器存储在对象头中。
对象通常在Eden区里诞生如果经过第一次Minor GC后仍然存活并且能被Survivor容纳该对象会被移动到Survivor空间中并且将其对象年龄设为1岁。对象在Survivor区中每熬过一次Minor GC年龄就增加1岁当它的年龄增加到一定程度默认为15就会被晋升到老年代中。
-XX:MaxTenuringThreshold设置对象晋升老年代的年龄阈值默认15
动态对象年龄判定
为了能更好地适应不同程序的内存状况
HotSpot虚拟机并不是永远要求对象的年龄必须达到-XX:MaxTenuringThreshold才能晋升老年代
如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半年龄大于或等于该年龄的对象就可以直接进入老年代无须等到-XX:MaxTenuringThreshold中要求的年龄。
空间分配担保
在发生Minor GC之前虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间大于则保证这次Minor GC是安全的否则看参数-XX:HandlePromotionFailure是否允许担保失败如果允许继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小大于将尝试进行一次Minor GC小于则进行一次Full GC。
JDK 6Update 24之后规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC否则将进行Full GC。-XX:HandlePromotionFailure参数不会再影响到虚拟机的空间分配担保策略