JVM自用笔记——堆

一. 什么是堆

在这里插入图片描述
几乎所有的对象实例和数组都应该在运行时分配到堆上。
 JVM启动时创建,一个jvm实例(一个进程)只有一个堆区,创建时便确定空间大小。堆的大小是可调节的。堆在物理上可以非连续,但是在逻辑上连续。但是不是所有堆空间都是线程共享的,还可以划分线程私有缓存区(TLAB)

栈堆方法区的关系
方法结束后,堆空间不会被立即回收,需要等待GC。

二. 堆的内部结构

java 7 之前: 新生代、老年代、永久代。 Java8之后,永久代被替换为了元空间。其中,元空间和永久代被看作是方法区的逻辑实现。
在这里插入图片描述

四. 参数设置

-Xms, -Xmx
在这里插入图片描述
m - memory
一旦堆区超过Xmx,那么将报oom
在这里插入图片描述
生产环境中,一般设置Xmx = Xms。
-XX:NewRatio(默认2,一般不调)
在这里插入图片描述
-XX:SurvivorRatio(默认8:1:1), -XX:UseAdaptiveSizePolicy
在这里插入图片描述
-XX:UseAdaptiveSizePolicy是自适应调整eden,survivor01,survivor02的大小比例。默认情况下是开启的。

  开启:-XX:+UseAdaptiveSizePolicy
  关闭:-XX:-UseAdaptiveSizePolicy

-Xmn:设置新生代空间的大小(与XX:NewRatio冲突)
-XX:MaxTenuringThreshold=:晋升老年代的存活次数阈值(0-15)。
-XX:HandlePromotionFailure空间分配担保,幸存区放不下直接晋升老年代
-XX:UseTLAB,开启TLAB空间
在这里插入图片描述

五. 对象分配过程

在这里插入图片描述
对象初始分配区域:Eden。当Eden满了,触发YGC/Minor GC(针对整个年轻代的垃圾回收).
幸存区通过复制算法维护。当对象存活次数到达阈值/或幸存区空间满了,晋升到老年代。
群体晋级

老年代满了则会触发Major GC。对于大对象而言,直接进入老年代。
在这里插入图片描述

六. Full GC、Major GC、Full GC

在这里插入图片描述
为什么要分代?
在这里插入图片描述在这里插入图片描述

七.TLAB

高效地保证线程安全
在这里插入图片描述

TLAB在Eden中仅占Eden空间的1%。堆空间上进行内存分配来完成的。由于多线程环境下,对象的分配可能存在竞争条件,需要使用同步机制来保证分配的正确性。然而,传统的同步机制会引入较大的开销,影响了内存分配的性能。线程在TLAB上进行对象分配时,无需加锁或同步,因为每个线程拥有自己的独立空间。

八. 逃逸分析

 随着逃逸分析的发展,对象不一定在堆中分配。如果一个对象没有逃逸出方法的话,那么将在栈上分配。通过-XX:+DoEscapeAnalysis
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
JIT编译器根据逃逸分析的结果,通常有如下优化方式

  1. 栈上分配
     如果一个对象没有逃逸出方法的话,那么将在栈上分配。即方法内new的对象,没办法在方法外被使用。
  2. 同步省略
     如果一个对象被发现只能通过一个对象被访问到,那么就可以通过锁消除省略掉针对该对象的同步
  3. 分离对象或标量替换
    在这里插入图片描述
    标量是数据被分割的最小单元。可以被继续分解的数据被称为聚合量。如果方法内new的对象,没办法在方法外被使用,那么可以通过分割为多个标量来实现栈上分配。

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值