3-JVM对象创建及内存分配
2021-04-14 22:50:45 1 举报
AI智能生成
JVM对象创建及内存分配
作者其他创作
大纲/内容
创建
1、校验是否类加载;否,则先加载
2、分配内存
划分内存方法
- 指针碰撞
内存规整:用过的内存放一边,没用过的放一边;中间用指针作为分界点,分配内存仅仅是把指针往空闲区挪动对象长度的位置。
- 空闲列表
内存不规整:虚拟机维护一个列表,记录空闲空间;再分配时在空闲空间给出一块够用的空间,并更新空闲空间列表。
并发问题
CAS:虚拟机采用CAS配上失败重试的方式保证更新操作的原子性来对分配内存空间的动作进行同步处理。
TLAB: 每个线程在Java堆中预先分配一小块内存。通过XX:+/ UseTLAB参数来设定虚拟机是否使用TLAB(JVM会默认开启XX:+UseTLAB),XX:TLABSize 指定TLAB大小。
3、初始化
虚拟机需要将分配到的内存空间都初始化为零值(默认值)
4、设置对象头
5、执行<init>方法
为属性赋值,执行构造方法
java对象为什么要指针压缩?
1、减少内存的消耗
2、.在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据, 占用较大宽带,同时GC也会承受较大压力
3、堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内 存不要大于32G为好
内存分配
流程
栈上分配
逃逸分析:确认对象只在方法内部使用,对象在栈内创建;该对象会随着栈帧出栈而销毁,减轻了垃圾回收的压力。
标量替换:jvm不会创建对象,而是分解为若干个被该方法使用的成员变量,这样就不需要一段连续的大空间来创建对象
Eden区(通常)
大对象直接进入老年代
- 前提:Serial 和ParNew收集器
- 例:字符串或者数组;-XX:PretenureSizeThreshold
- 为什么?为了避免为大对象分配内存时的复制操作而降低效率。避免Eden和S区的复制
年龄达到15进入老年代
动态年龄判断
- 概念:一批对象的总大小大于这块Survivor区域内存大小的 50%(-XX:TargetSurvivorRatio可以指定),那么此时大于等于这批对象年龄最大值的对象,就可以直接进入老年代
- 例:如Survivor区域里现在有一批对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时就会 把年龄n(含)以上的对象都放入老年代
- 为什么? 希望那些可能是长期存活的对象,尽早进入老年代。一般在minor gc之后触发
老年代担保
finalize()方法
重写了该方法,则不会被立刻回收;而是执行该方法,在该方法中有引用了其他对象,那么产生GC ROOT,该对象有死而复生。
0 条评论
下一页