深入理解Java 虚拟机(周志明)笔记(六)——Java内存分配
2016-03-10 22:30
281 查看
5.2.内存分配
可用参数 -Xmx 最大可用内存
-Xms 初始内存
-Xmn 新生代内存
-XX:SurvivorRatio 设置年轻代中Eden区与一个Survivor区的大小比值
-XX:PretenureSizeThread 设置大于此值得对象直接在老年代分配(仅对SSerial和ParNew有效)
-XX:MaxTenuringThread设置对象晋升到老年代的年龄阈值
规则:1.对象优先在新生代的Eden区分配
大多数情况下,对象在新生代Eden上分配。当Eden区没有足够空间时,虚拟机发起一次Minor GC(复制算法),
若Minor GC中发现当前存活对象放入Survivor空间若成功,则推出GC再次测试分配对象;
若无法完全放入Survivor空间,则采用分配担保机制将当前存活对象放入老年代,然后推出GC,再尝试继续分配对象。
2.大对象直接进入老年代
大对象:指需要大量连续空间的对象,如很长的字符串及数组。
避免使用大量的”短命大对象“,以避免在内存有大量空间时提前触发GC。
-XX:PretenureSizeThread 设置大于此值得对象直接在老年代分配,以避免在Eden区及两个Survivor区之间发生大量的内存复制。
3.长期存活的对象将进入老年代
1.虚拟机为每个对象设置一个对象年龄计数器。若对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1.对象每在Survivor区每“熬过”一次Minor GC,年龄就增加1岁,当它年龄增加到一定程度(默认为15岁),就将会被晋升到老年代中。
对象晋升到老年代的年龄阈值可通过参数-XX:MaxTenuringThread设置。
4.动态对象年龄判定
为了更好的适应不同程序的内存状况,虚拟机并不是永远的等到对象年龄必须达到MaxTenuringThread才能晋升老年代,
如果在Survivor区中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。
5.空间分配担保
1.由于新生代采用复制算法,故有可能Minor GC中有大量存活对象,不能被Survivor存储,此时就需要老年代内存做为分配担保,把Survivor无法容纳的对象直接进入老年代。同时虚拟机提供HandlePromotionFailure参数 设置是否允许担保失败。
2.担保过程:在发生Minor GC前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象的总和,若大于这Minor GC是可以确保安全的。若不大于,则虚拟机检查HandlePromotionFailure的值,若允许担保失败继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小(经验值),若大于,则尝试进行一次Minor GC,虽然是有风险的;若小于或HandlePromotionFailure不允许担保失败则进行一次Full GC。
可用参数 -Xmx 最大可用内存
-Xms 初始内存
-Xmn 新生代内存
-XX:SurvivorRatio 设置年轻代中Eden区与一个Survivor区的大小比值
-XX:PretenureSizeThread 设置大于此值得对象直接在老年代分配(仅对SSerial和ParNew有效)
-XX:MaxTenuringThread设置对象晋升到老年代的年龄阈值
规则:1.对象优先在新生代的Eden区分配
大多数情况下,对象在新生代Eden上分配。当Eden区没有足够空间时,虚拟机发起一次Minor GC(复制算法),
若Minor GC中发现当前存活对象放入Survivor空间若成功,则推出GC再次测试分配对象;
若无法完全放入Survivor空间,则采用分配担保机制将当前存活对象放入老年代,然后推出GC,再尝试继续分配对象。
2.大对象直接进入老年代
大对象:指需要大量连续空间的对象,如很长的字符串及数组。
避免使用大量的”短命大对象“,以避免在内存有大量空间时提前触发GC。
-XX:PretenureSizeThread 设置大于此值得对象直接在老年代分配,以避免在Eden区及两个Survivor区之间发生大量的内存复制。
3.长期存活的对象将进入老年代
1.虚拟机为每个对象设置一个对象年龄计数器。若对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1.对象每在Survivor区每“熬过”一次Minor GC,年龄就增加1岁,当它年龄增加到一定程度(默认为15岁),就将会被晋升到老年代中。
对象晋升到老年代的年龄阈值可通过参数-XX:MaxTenuringThread设置。
4.动态对象年龄判定
为了更好的适应不同程序的内存状况,虚拟机并不是永远的等到对象年龄必须达到MaxTenuringThread才能晋升老年代,
如果在Survivor区中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。
5.空间分配担保
1.由于新生代采用复制算法,故有可能Minor GC中有大量存活对象,不能被Survivor存储,此时就需要老年代内存做为分配担保,把Survivor无法容纳的对象直接进入老年代。同时虚拟机提供HandlePromotionFailure参数 设置是否允许担保失败。
2.担保过程:在发生Minor GC前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象的总和,若大于这Minor GC是可以确保安全的。若不大于,则虚拟机检查HandlePromotionFailure的值,若允许担保失败继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小(经验值),若大于,则尝试进行一次Minor GC,虽然是有风险的;若小于或HandlePromotionFailure不允许担保失败则进行一次Full GC。
相关文章推荐
- Java递归算法实例
- Java中的流与文件:流
- 深入理解Java 虚拟机(周志明)笔记(五)——垃圾收集器(三)
- eclipse启动后闪退
- 深入理解Java 虚拟机(周志明)笔记(五)——垃圾收集器(二)
- java算法小知识练习(二)
- Java常用类库
- Java常识之-注解
- myeclipse10的Mybatis插件 Generator最完整配置详解
- java IO复习(二)
- java学习心得
- 反射
- java内存
- moon jdk目录
- Java中堆内存与栈内存分配浅析
- 阿里一面准备工作<java部分>
- java学习笔记
- LeetCode : Longest Valid Parentheses [java]
- Java基础复习系列一
- Spring MVC 基于URL的映射规则(注解版)