JVM(五)内存分配

一.Java堆内存分布图

二.对象的分配规则

1.对象主要分配在新生代的Eden区上

2.如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。TLAB的全称是Thread Local Allocation Buffer,即线程本地分配缓存区,这是一个线程专用的内存分配区域。

3.少数情况下也可能直接分配在老年代(对象过大,超过Eden区大小或者From区大小)

三.GC参数指定垃圾回收

-Xms20M、-Xmx20M、-Xmn10M这3个参数限制了Java堆大小为20MB,不可扩展,其中10MB分配给新生代,剩下10M分配给老年代。-Xx:SurvivorRatio=8决定了新生代中Eden区与两个Survivor区的空间比例是8:1

四.新生代与老年代回收

新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度比较快。

老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般比Minor GC慢10倍以上。

五.指定大对象超过一定大小直接分配在老年代参数

虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这个设置值得对象直接在老年代分配。这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存复制

六.逃逸分析

逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,称为方法逃逸。甚至还有可能被外部线程访问到,譬如赋值给类变量或可以在其他线程中访问的实例变量,称为线程逃逸。

七.栈上分配

栈上分配就是把方法中的变量和对象分配到栈上,方法执行完后自动销毁,而不需要垃圾回收的介入,从而提高系统性能

八.FullGC触发条件

1.调用System.gc():此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发Full GC。因此强烈建议能不使用此方法就不要使用,让虚拟机自己去管理它的内存,可通过-XX:+DisableExplicitGC来禁止RMI调用System.gc()

2.老年代空间不足:老年代空间不足的常见场景为前文所讲的大对象直接进入老年代、长期存活的对象进入老年代等,当执行Full GC后空间仍然不足,则抛出oom。为避免以上原因引起的Full GC,调优时应尽量做到让对象在Minor GC阶段被回收,让对象在新生代多存活一段时间以及不要创建过大的对象以及数组

3.空间分配担保失败:使用复制算法的Minor GC需要老年代的内存空间作担保,如果出现了HandlePromotionFailure担保失败,则会触发Full GC

九.频繁创建大对象导致频繁FullGC解决办法:

1.最大内存-xmx大小缩小,从而缩短FULL GC

2.集群部署这样每个节点的最大内存不会太大,发生FULL GC执行的时间不会太长

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值