JVM内存模型以及参数设置(二)

前言

本文将从创建对象、对象内存分配、对象内存回收三个方面,详细介绍JVM的参数设置。

一、创建对象

以user.java这个类为例子,当new user()一个user对象时,JVM经历的流程为:
1、类加载检查:JVM会检查user类是否已经被加载(具体参考之前写的从源码带你看jvm类加载机制)。
2、分配内存:jvm给对象分配内存有两种方式:指针碰撞空闲列表。指针碰撞是假设堆内存不存在碎片化,以一个指针为分界点,指针另一边是空闲空间。当new 一个对象时,指针会根据对象所需内存的大小挪动相同的距离,正好可以存储新建的对象。空闲列表针对的是堆空间不规整的情况,jvm会维护一个列表,专门记载堆中哪些空间是可用的,当new一个对象时,会从列表中划分一块足够大小的空间给对象。
在这里存在一个问题当多个对象同时申请堆空间时,会存在并发情况。
为了解决这个问题,jvm采用CAS和本地线程分配缓冲两种方式。前者是失败重试的方式,后者则是给每个线程在堆空间(在年轻代中)中分配一小块内存,用来存放new 对象
3:初始化:jvm默认将分配到的对象空间初始化为0,这样即使不给对象赋值也可以直接使用该对象。
4、设置对象头:每一个new 的对象都有对象头、实例数据和对齐填充。对象头中有MarkWord标记字段(存放锁状态和分代年龄等数据)、Klass Point类型指针(类型指针比较难理解,对于一个user类,他的new对象是分配在堆空间,但是它的类元素信息是放在方法区的,这个类型指针就是指向方法区中类信息的一个指针。一般是4个字节)
5、执行方法:这个是底层C语言写的,了解即可。

注意:在创建对象的时候,会进行指针压缩(:­XX:+UseCompressedOops这个参数设置,默认是开启)。指针压缩是为了节省内存空间。堆内存小于4G时不需要压缩,大于32G时,指针压缩的技术还没开发出来。所以堆内存空间也不是越大越好。

二、对象内存分配

1、栈内分配:当对象较多时,堆空间会产生较大的压力,因此并不是所有的对象都是在堆中分配空间。当一个对象经过逃逸分析(开启-XX:+DoEscapeAnalysis)发现该对象并没有被外部引用,jvm会将该对象通过标量替换((-XX:+EliminateAllocations)分配到栈上。
2、对象存放在堆中:当new user()对象时,会判断对象是否过大,如果不是大对象(
-XX:PretenureSizeThreshold
)就会分配到eden区,若是大对象会直接分配到年老代。
注意:在这里我们分析一下如何分配年轻代和年老代的空间,以尽可能减少full gc 的次数。
1、尽量增大年轻代的空间,特别注意survivor空间大小。举个例子,假设user对象大小是60m,Eden区是800M,survivor两个区总共200m。若是user对象是在minor gc时刚刚创建,那user对象肯定不可能清除掉,只能存放起来。然而在这个时候Eden已经满了马上就要gc,所以user只能存放在s0(s0是100m,当对象的大小超过s0的50%时,这个对象会直接存放在年老代中,当然这个值-XX:TargetSurvivorRatio可以设置),最后这个对象会存放在年老代中。这样就会j非常容易导致full gc。但是,若是将年轻代的空间增大,那么s0就可以存储user对象,下次minor gc 时,就会将user对象清除掉,大大降低了full gc的概率。
2、对象内存分配还有很多要点,比如对象年龄判断,年老代空间分配担保机制等等。

三、对象内存回收

对象内存回收的判断有两种方式:引用计数法和可达性分析
1、引用计数法:给对象添加一个计数器,若是有地方引用了该对象就给计数器+1,若是不引用了就-1,当计数器是0的时候,就回收该对象。(这个方法很少用,主要是因为容易出现对象直接互相引用,造成一个死循环。)
2、可达性分析:以GC ROOTS为根节点,然后在这个根节点上的对象都给标记非垃圾对象,将不在根节点上的对象回收掉。

总结

在对象被回收之前还有一次机会,finalize()方法判断这个对象是否是垃圾对象。如果没有finalize()方法,会直接回收掉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值