JVM之JVM初探

简介: JVM之JVM初探

JVM初探

JVM

执行文件

JVM执行的文件为class文件,这个执行文件是什么意思呢,就是虚拟机能够识别的文件,类加载器加载链接初始化后将数据保存在JVM运行时数据区中的文件。

类装入子系统

JVM的类加载器为ClassLoader采用双亲委派模型机制进行加载类。

双亲委派模型机制:

根据父子关系一直往顶层找是否被其他父级parent类加载器加载过,如果找到加载过,返回;如果没有找到,在返回一个一个查找是否有加载的权限,如果有就加载;如果这个时候所有的父级parent类加载器都没有加载过而且没有权限加载,那么自己去加载。

注意:父级parent类加载器不是继承的父子关系,而是一个ClassLoader中的一个parent变量代表父级类加载器。

执行引擎

Java的执行引擎包括解释器,JIT即时编译器,垃圾回收器。解释器不用介绍了,将Java字节码指令翻译为机器能够识别的指令;JIT即时编译器是因为光靠解释运行的效率低,所以对于热点代码进行编译为机器指令以加快运行效率(刚开启的时候得先需要通过解释器解释运行,当符合热点代码的特征时,会直接编译成本地代码之后热点代码就可以直接运行不用在经过解释再运行了。即解释器先运行一段时间才能够真正提升效率);

垃圾回收器,Java能够流行的一个原因还有这个特点:他不用管理内存,由JVM的垃圾回收器自动进行回收垃圾,达到管理内存的目的。

垃圾回收器

JVM运行时内存结构为:PC程序计数器、本地方法栈、虚拟机栈、堆、方法区。其中程序计数器,本地方法栈、虚拟机栈等都是线程私有的,也就是每条线程都拥有这三块区域,而且会随着线程的创建而创建,线程的结束而销毁,因此这三个区域不需要垃圾回收。

堆中的内存回收

这里讲解下垃圾回收器如何判定一个对象是否为垃圾的算法:

1.引用计数器:

之前Java中判断垃圾的算法使用引用计数器进行判定的,对象中有一个字段保存着计数器,只要这个对象被引用了那么计数器就加1;释放了这个引用就计数器减1。垃圾回收器回收的时候看这个对象的引用是否为0,如果为0那么代表这个对象是垃圾,该被回收。

即A引用B,假如这个时候没有其他引用指向A,那么A的计数器为0,B的计数器是1;当A把B的引用释放之后,B也为0,下次垃圾回收的时候就会将A,B回收。

这么看好像也没有问题,但是如果我的两个对象互相引用对方,A要销毁依赖于B,而B销毁依赖于A,这个时候垃圾回收器就不会回收这两个对象,也就是无法解决循环引用的问题。

举例:创建A对象a,创建B对象b。

这个时候A的成员变量引用b,B的成员变量引用a。即a和b的计数器都为1,销毁a的时候发现b在引用a,销毁b的时候发现a在引用b。垃圾回收的时候就不会回收这两个对象,但是除此之外没有其他引用指向这两个对象。

循环引用会导致即使外界已经没有任何指针能够访问他们了,但是他们所占资源仍然无法释放的情况。

优点:不需要STW,找到计数器为0的对象直接进行清除

缺点:维护计数器空间和时间上都有所牺牲,而且无法解决循环引用。

2.GC Root(根可达算法)

上面的算法无法解决循环引用问题,如果这个时候规定一些永远不会被回收的对象只要能被这些对象引用,那么就不是垃圾,这个时候就是GC Root的算法。

一个对象只要一直往上找最终能找到GC Root那么就不是垃圾,如果找不到就是垃圾。这个向上找的链叫做引用链,和GcRoot没有任何链接的称为“垃圾”

**一般而言可以作为Gc Root根节点的有:方法区静态信息,方法区常量信息,Java虚拟机栈所引用的对象,本地方法栈所引用对象。 **

方法区中的内存回收

方法区用于存储已被虚拟机加载的类型信息,常量,静态变量,被即时编译器编译后的代码缓存。
也就是存放类型信息、常量、静态变量、即时编译器编译后的代码缓存、域信息、方法信息等。

如下图:

类型信息:

域信息:

方法信息

方法区中清除垃圾常量和垃圾类

1.常量:

常量不被引用,就会从常量池中清除

2.类:

需要满足以下条件:

1.该类的所有对象都已被清除

2.该类的java.lang.Class对象没有被任何对象或变量引用。只要一个类被虚拟机加载进方法区,那么在堆中就会有一个代表该类的对象:java.lang.Class。这个对象在类被加载进方法区的时候创建,在方法区中该类被删除时清除。

3.加载该类的ClassLoader已经被回收

关于回收的那些事

1.当触发GC时,对象被标记为垃圾就一定会被回收吗?

2.GCRoots就是固定的那些值吗?有没有可能会随着程序的运行而增加新的GCRoots?

1.当对象被标记为垃圾时,要清除其实还有一次标记过程,也就是说对象要被清除得经过两次标记过程:

当对象经过可达性分析后发现没有与GCRoots相关的引用链,他会被第一次标记,接着会进行判断是否要进行调用对象的finalize()方法,【判断条件:对象重写该方法并且该对象没有执行过该方法】。

第一种情况:

如果有必要执行finalize()方法的话,会将该对象添加到一个F-Quene的队列里面,稍后会有一个虚拟机自己建立并且调度优先级很低的Finalizer线程去执行对象的finalize()方法,由于该方法可能会陷入死循环或者执行缓慢导致队列中的其他对象永远不被调用finalizy方法,所以该方法并不一定保证能够执行完。接着稍后会对该队列中的对象进行第二次标记,如果还是没有对象引用它,那么将会被回收;如果有对象引用了它那么会进行将该对象移除队列中。

第二种情况:

如果没有必要执行【有两种情况:1.该对象没有重写该方法 2.该对象的finalizy方法已经执行过了】也就是说一个对象只有第一次GC被标记的时候可能逃逸不被回收,但是第二次GC标记的话就不行了。

提示:JAVA中并不提倡重写这个方法,最初是因为C和C++的人更容易接受JAVA。

2.GCRoots通常一般是以下对象:

1.在虚拟机栈的本地变量表中引用的对象

2.方法区中静态属性引用的对象

3.方法区中常量池中引用的对象

4.本地方法JNI中引用的对象

5.Class对象,常驻的异常对象(NullPointException,OOM等),系统类加载器

6.同步锁中持有的对象(比如Synchronized)

7.本地代码缓存

这些是固定的GCRoots集合,但是根据不同的垃圾收集器和当前回收区域内存的不同,还可以有其他对象“临时”加入GCRoots集合。

垃圾收集器中将堆划分为了不同的内存区域,这部分后面详解。当出现这么一种情况:老年代的对象引用年轻代的对象的时候,年轻代中的对象回收的时候不仅要遍历GCRoots是否有引用链之外,还需要遍历是否老年代有引用。这就意味着要把老年代全部遍历一遍才能确认是垃圾。

因此出现了记忆集这个概念:在新生代上建立一个数据结构(记忆集),这个结构里面将老年代的内存划分开,标识哪部分内存是跨域访问的对象(比如访问年轻代里面的对象)。当发生年轻代的GC时,会将这个数据结构里面的老年代对象标识为GC Roots进行扫描,而不用进行遍历整个老年代。【只有在记忆集中包含的小块内存里的对象才会被加入到GC Roots中】


相关文章
|
1天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
11天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
449 192
|
3天前
|
数据采集 消息中间件 人工智能
跨系统数据搬运的全方位解析,包括定义、痛点、技术、方法及智能体解决方案
跨系统数据搬运打通企业数据孤岛,实现CRM、ERP等系统高效互通。伴随数字化转型,全球市场规模超150亿美元,中国年增速达30%。本文详解其定义、痛点、技术原理、主流方法及智能体新范式,结合实在Agent等案例,揭示从数据割裂到智能流通的实践路径,助力企业降本增效,释放数据价值。
|
9天前
|
人工智能 自然语言处理 安全
国内主流Agent工具功能全维度对比:从技术内核到场景落地,一篇读懂所有选择
2024年全球AI Agent市场规模达52.9亿美元,预计2030年将增长至471亿美元,亚太地区增速领先。国内Agent工具呈现“百花齐放”格局,涵盖政务、金融、电商等多场景。本文深入解析实在智能实在Agent等主流产品,在技术架构、任务规划、多模态交互、工具集成等方面进行全维度对比,结合市场反馈与行业趋势,为企业及个人用户提供科学选型指南,助力高效落地AI智能体应用。
|
5天前
|
消息中间件 安全 NoSQL
阿里云通过中国信通院首批安全可信中间件评估
近日,由中国信通院主办的 2025(第五届)数字化转型发展大会在京举行。会上,“阿里云应用服务器软件 AliEE”、“消息队列软件 RocketMQ”、“云数据库 Tair”三款产品成功通过中国信通院“安全可信中间件”系列评估,成为首批获此认证的中间件产品。此次评估覆盖安全可信要求、功能完备性、安全防护能力、性能表现、可靠性与可维护性等核心指标,标志着阿里云中间件产品在多架构适配与安全能力上达到行业领先水平。
315 195

热门文章

最新文章