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