java内存的分配策略

1. 内存分配策略


按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的。静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间。这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求。

栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的。和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。

静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例。堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。

2.对象优先在Eden分配

** 大多数情况下,对象在新生代Eden去中分配,(注:java堆中的新生代可分为Eden区和两个Survivor区),当Eden区中没有足够的空间进行分配时,虚拟机将发起一次Minor GC。 **

Minor GC 和 Full GC的区别

  • 新生代GC(Minor GC):指的是发生在新生代中的垃圾收集动作,java对象的创建和回收非常频繁,所以Mnior GC非常频繁,一般回收速度也比较快。
  • 老年代GC(Major GC/Full FC):指发生在老年代中的GC,出现了Major GC经常会伴随至少一次的Minor GC(并非绝对),Major GC的速度一般会比Minor GC慢10倍以上。Full FC=Minor GC+Major GC

3.大对象直接进入老年代

大对象是指,需要大量连续内存空间的java对象(写程序的时候应该避免“短命大对象”),经常出现大对象,容易导致内存还有不少空间时,就提前触发垃圾收集以获取足够的连续空间来分给他们。
虚拟机提供-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接进入老年代,这么做为目的是为了避免在Eden以及两个Survivor区之间发生大量的内存复制(新生代的垃圾收集算法采用复制算法)。

4.长期存活的对象将进入老年代

虚拟机给每个对象定义一个对象年龄(Age)的计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1.其在Survivor中没经历一次Minior GC,Age就加1,当其Age增加到一定程度(默认15岁),就将其晋升到老年代。年龄阈值可以通过参数-XX:MxTenuringThreshold设置。

5.动态对象的年龄判定

为了能更好的适应不同程序的内存状况,虚拟机不是永远地要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代。

6.空间分配担保

在发生Minor GC之前,虚拟机会先检查老年代中最大可用连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于将尝试进行一次Minor GC。如果小于或者HandlePromotionFailure设置为不允许,那这时就改为一次Full GC。注:在JDK 6 Update 24之后,虚拟机已经不再使用HandlePromotionFailure参数了,规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC。
分配担保解释:
新生代使用复制算法完成垃圾收集,为了节约内存Survivor的设置的比较小,当Minor GC后如果还有大量对象存活,超过了一个Survivor的内存空间,这时就需要老年代进行分配担保,把Survivor中无法容纳的对象直接进入老年代。若虚拟机检查老年代中最大可用连续空间大于新生代所有对象总空间那么就能保证不需要发生Full GC,因为老年代的内存空间够用。反之,如果老年代中最大可用连续空间小于新生代所有对象总空间就需要在尝试Minor GC失败后进行Full Gc或者直接Full GC。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值