首页 > 其他分享 >jvm-第三节jvm中的对象及引用

jvm-第三节jvm中的对象及引用

时间:2023-06-20 17:04:06浏览次数:38  
标签:第三节 对象 gc 引用 jvm 分配内存 分配

jvm中的对象以及引用

问题

这篇文章主要探讨的几个问题:

  1. jvm中对象创建过程
  2. 对象的内存布局
  3. 对象的访问方式
  4. 如何判断对象是否存活
  5. 对象分配策略
  6. 四种引用的区别

jvm中对象的创建过程

  1. 检查加载:检查指令是否在一个常量池中定位到一个类的符号引用(一组符号描述所引用的目标),检查类是否加载解析初始化
  2. 分配内存:从jvm的堆中划分一块内存,这个划分有俩种情况,分别是指针碰撞和空闲列表
  1. 指针碰撞:如果jvm堆中的空间是规整的,空闲一边,用过的一边,中间放一个指针,那么分配内存仅仅是吧指针挪动与对象大小等距距离;具体如图
  2. 空闲列表:如果jvm堆种地空间不规整,那就需要维护一个空闲列表,分配时在空闲列表上找一块足够大的空间分配给对象,然后维护列表,具体如图
  3. 分配内存的并发安全问题:在多线程情况下分配内存,创建对象,是一个极其频繁的为题,t1线程创建对象分配内存修改指针没结束,t2就进来使用原指针分配内存,针对这个问题有俩种解决方式,一种是CAS,一种是分配缓冲TLAB
  1. CAS:通过cas操作,如果成功就分配内存,如图
  2. TLAB:是一种基于线程本地缓存方式,通过cas分配内存,每次分配时现在自己的TLAB中找,如果没有空间了就采用其他分配方式,比如直接分配;
  3. 分配缓冲:预先获取一块连续的内存,然后将缓冲池分成多块,每次分配对象就从缓冲池中拿一块进行分配;如果没有空间了,则会使用其他分方式,比如直接分配;
  1. 初始化零值:被分配内存空间的对象都要初始化零值,int =0 boolean =false这一步的意义是保证java对象在不赋值初始化的情况下可以使用
  2. 设置对象头:jvm对对象的必要设置,包括这个对象是哪个类的实例,如何找到类的元数据,对象hash ,gc,等信息,都在对象头中;具体看下面
  3. 初始化对象:对于jvm来说,一个对象已经创建完了;

对象的内存布局

jvm-第三节jvm中的对象及引用_数据

  1. 在hotspot中对象的布局分为三类。分别是对象头,实例数据,对齐填充,分别介绍一下
  1. 对象头:存储的是运行的数据它包含三部分,存储对运行数据(markWord),类型指针,若是数组类型,有记录数组长度的记录
  1. 存储对象自身运行时数据包含 haah,gc分代年龄,锁标识,锁类型,偏向线程id,偏向时间戳
  1. 实例数据
  2. 对齐填充

对象的访问方式

  1. 句柄:如果采用句柄访问,jvm堆中会划分一块区域做句柄池,reference(在对象头中)中村的是句柄的地址,句柄中存的是对象实例和类型数据的地址
  2. 直接指针:reference中存的就是对象地址
  3. 对比:直接指针访问块,但是对象变更速度太快,所以一直修改开销大,句柄要二次访问慢,但是对面变更是句柄维护,reference中不需要修改。

判断对象是否存活的方式

  1. 堆中存放着几乎所有的对象,gc回收时要判断这些对象是否存活,如何判断存活,常见的有引用计数法,可达性分析
  1. 引用计数法:在对象中添加引用计数器,每当有一个地方引用就+1,失效时就-1,存在相互引用情况要引入额外基质处理,影响效率;
  2. 可达性分析:通过gc root作为起点,从这个节点开始向下搜素,沿途路径叫引用链,当一个对象到gc root没有任何引用链,则证明这对象不可用;
  1. 常见的gc root如下
  1. 虚拟机栈中引用的对象
  2. jvm-第三节jvm中的对象及引用_数据_02

  3. 本地方法栈中引用的对象
  4. jvm-第三节jvm中的对象及引用_句柄_03

  5. 方法区静态属性引用的对象
  6. jvm-第三节jvm中的对象及引用_数据_04

  7. jni引用的对象
  8. jvm-第三节jvm中的对象及引用_句柄_05

  9. 虚拟机内部引用的对象,如常量池引用的对象
  10. jvm-第三节jvm中的对象及引用_句柄_06

  11. jvm引用类型,软弱虚引用
  12. 根集合中的对象,在gc前预设好的对象
  1. Finalize 方法 (没啥用)
    即使通过可达性分析判断不可达的对象,也不是“非死不可”,它还会处于“缓刑”阶段,真正要宣告一个对象死亡,需要经过两次标记过程,一次是 没有找到与 GCRoots 的引用链,它将被第一次标记。随后进行一次筛选(如果对象覆盖了 finalize),我们可以在 finalize 中去拯救。

四种对象引用以及区别

  1. 强: Object obj = new Object(); // 强引用
  2. 软:SoftReference<Object> sr = new SoftReference<>(new Object()); // 软引用
  3. 弱: WeakReference<Object> wr = new WeakReference<>(new Object()); // 弱引用
  4. 虚: WeakReference<Object> wr = new WeakReference<>(new Object()); // 弱引用
  5. 他们之前的区别:那gc为例,
  1. 强引用-obj存在就不会回收
  2. 软引用-当内存不足时,会被回收
  3. 弱引用-下一次gc时就会被回收
  4. 虚引用-每逢gc必然回收,放入特殊队列

对象分配策略

  1. 除了常见的分配在堆中,还会分配到栈中,既逃逸下面详细说
  2. 对象的分配
  1. 栈上分配
  1. 首先说逃逸分析,分为俩种,一种是线程逃逸,既被多个线程访问的对象,另一种是方法逃逸,既被其他方法引用
  2. 如果对象没有逃逸,则在栈上分配对象,这样就会避免对象创建和回收;
  3. 举个例子,myobject属于不可逃逸,jvm在栈上分配
  4. jvm-第三节jvm中的对象及引用_初始化_07

  1. 堆中分配:
  1. 对象优先在堆中的eden:大多数情况下对象在eden上分配,空间不够就minor gc,这里会涉及道空间分配担保机制;
  2. 大对象直接进入老年代
  3. 长期存活的进入老年代:每一个对象有一个年龄计数器(在对象头的运行时数据区中的gc年龄),达到一定阈值就会进入老年代


标签:第三节,对象,gc,引用,jvm,分配内存,分配
From: https://blog.51cto.com/u_12550160/6523960

相关文章

  • vue3+vite 动态引用静态资源,动态引入assets文件夹图片的几种方式
    可以参考这个回答,亲测有用 https://blog.csdn.net/weixin_43743175/article/details/125892613 ......
  • JVM 入门
    JVM区域划分JVM内存大小=堆+非堆组成堆由三部分组成,Eden(伊甸园),SurFromandSurTo(幸存者),Ten(老年区).注:Sur0/1和SurFrom/To是一回事非堆由三部分组成,metaspace(元空间),codeCache,ClassSpace比例老年代:年轻代=2:1eden:surFrom:surTo=8:......
  • JVM监控工具jstat使用介绍
    jstat是Java自带的一个命令行工具,用于监控JVM运行时的状态信息。它可以通过以下格式的命令来调用:jstat[option]<vmid>[<interval>[<count>]]其中,option表示需要查询的信息类型,如-gc,-class,-compiler等;vmid表示目标JVM的进程ID或者进程名;interval表示查询......
  • Docker Compose 引用环境变量
    ComposeCLI与环境变量ComposeCLI(composecommand-line即docker-compose程序)能够识别名称为COMPOSE_PROJECT_NAME和COMPOSE_FILE等环境变量(具体支持的环境变量请参考这里)。比如我们可以通过这两个环境变量为docker-compose指定project的名称和配置文件:$exportC......
  • 如何查看JVM运行的堆内存情况
    《不可不知的7个JDK命令》介绍了些jdk自带的问题排查工具,机器出现CPU飙升的情况,此时就可以借助工具,排查应用端是否存在一些潜在问题。jmap指令可以查看JVM运行的堆内存情况,[test@localhost]>jmap-hUsage:jmap[option]<pid>(toconnecttorunningprocess)......
  • 毕业论文里引用文献率为0%的解决小技巧
    快要毕业了,带着伤感,大学生们已开始加紧完成论文的编写和毕业答辩,祝大家都可以顺利拿到学位证书和毕业证书。前两天,有位同学找我,咨询如何解决毕业论文里,引用文献率为0%的问题。我在知网上将该论文通查一遍,查重部分都是“是否引证:否”。第一次发现还有学校对文献引用率有要求,......
  • 第三节:ChatGPT聊天框用途(PPT/思维导图/写代码/文案/面试等等)
    一. 制作PPT       二.思维导图       三.         !作       者:Yaopengfei(姚鹏飞)博客地址:http://www.cnblogs.com/yaopengfei/声     明1:如有错误,欢迎讨论,请勿谩骂^_^。声     明2:......
  • 必知必会:JVM
    JVM-Java虚拟机Java程序运行时,编译器将Java文件编译成平台无关的Java字节码文件(.class)。对应平台JVM对字节码文件进行解释,翻译成对应平台匹配的机器指令并运行。JVM内存区域(内存结构)JVM内存区域粗略划分为堆和栈。按虚拟机规范划分为五部分,包括程序计数器、虚拟机栈、本......
  • 美团一面:OOM后,JVM一定会退出吗?为什么?
    文章且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪酬猛......
  • 【详解C++中的引用】
    @TOC一、什么是引用引用就是给一个变量取别名。注意:这个引用不会新开辟一块空间,而是和原来的变量公用一块空间。举个例子:李逵,在家称为"铁牛",江湖上人称"黑旋风"。二、引用规则引用规则:引用实体类型+&+引用别名=引用实体。比如下面:intmain(){ inta=10; //引用 int&ba=a......