深入了解JVM底层原理

一、JVM内存结构

1、方法区:存储编译后的类、常量等(.class字节码文件

2、堆内存:存储对象

3、程序计数器:存储当前执行的指令地址(计算机处理器(CPU)正在执行的下一条指令在内存中的地址)

4、虚拟机栈:java栈,存储局部变量、方法参数、返回值以及异常处理信息

5、本地方法栈:存储本地方法的执行状态信息以上是JVM内存结构的主要部分,其中除了方法区外其他部分都是java程序员直接操作和调优的重要部分

线程私有:程序计数器、虚拟机栈、本地方法栈。

线程共享:方法区、堆。

以下是一个更完整的示例代码,演示了JVM内存结构的各个部分:

public class MemoryStructureExample {// 静态变量,存储在方法区private static String staticVar = "Static Variable";public static void main(String[] args) {// 局部变量,存储在虚拟机栈int localVar = 10;// 创建一个对象实例,存储在堆内存MemoryStructureExample obj = new MemoryStructureExample();// 调用方法,会在虚拟机栈中创建方法调用的栈帧obj.method();}// 实例方法public void method() {// 方法中的局部变量,存储在虚拟机栈String localVar2 = "Local Variable";// 创建一个对象实例,存储在堆内存Object obj = new Object();// 调用本地方法,本地方法栈存储本地方法的执行状态信息System.out.println(System.currentTimeMillis());}
}

在这个示例中,我们展示了JVM内存结构的各个部分的应用:

  • 静态变量staticVar存储在方法区;
  • main方法中的局部变量localVar存储在虚拟机栈;
  • MemoryStructureExample对象实例存储在堆内存;
  • method方法中的局部变量localVar2也存储在虚拟机栈;
  • 方法中创建的Object对象实例也存储在堆内存;
  • 调用本地方法System.currentTimeMillis()时,本地方法栈存储本地方法的执行状态信息。

二、JVM垃圾回收

        GC 的目的在于实现堆内存中无用对象内存自动释放,减少内存碎片、加快分配速度 。线程私有的不存在垃圾回收,线程共享才存在垃圾回收。以下我们围绕如何发现垃圾和如何进行垃圾回收进行详细描述:

(一)如何发现垃圾?

1、引用计数算法

        引用计数算法核心思想是,堆中的对象每被引用一次,则计数器加 1,每减少一个引用就减 1,当对象的引用计数器为 0 时可以被当作垃圾收集。

优点:效率高,比较快

缺点:无法检测出循环引用,如两个对象互相引用时,他们的引用计数永远不可能为 0

2、可达性分析(根搜索)算法

        根搜索算法是把所有的引用关系看作一张图,从一个节点 GC ROOT 开始,寻找对应的
引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕
之后,剩余的节点则被认为是没有被引用到的节点,即可以当作垃圾。

3、三色标记法(黑灰白)

        三色标记法是用三种颜色记录对象的标记状态。这种算法通过标记对象的颜色来表示它们的状态,以确定哪些对象是活动的,哪些是垃圾对象。黑色-已标记,灰色-标记中,白色-未标记。原理是通过将引用链上的对象全部标记,最终剩余的不在引用链上的对象全部是白色的(未标记的),然后对未标记的无用的对象进行回收。这种算法通过标记对象的颜色来表示它们的状态,以确定哪些对象是活动的,哪些是垃圾对象。

3.1起始的三个对象还未处理完成,用灰色表示

3.2该对象的引用已经处理完成,用黑色表示,黑色引用的对象变为灰色

3.3依次类推

3.4沿着引用链都标记了一遍

3.5最后为标记的白色对象,即为垃圾

(二)如何清除垃圾?

1、标记清除算法(空间碎片,CMS)

        标记清除算法是通过GC Root引用链往下查找,对于引用链上有引用的对象进行标记,然后对之外的无用的对象进行清除。缺点是存在内存碎片的问题。

2、标记整理算法(性能较差,G1)

        标记整理算法是在标记清除算法上多了一步整理的操作,去除了空间碎片的问题。缺点是性能较差

3、标记复制算法(占用成倍的空间

        3.1将整个内存分成两个大小相等的区域,from 和 to,其中 to 总是处于空闲,from 存储新创建的对象。

        3.2标记阶段与前面的算法类似。

        3.3在找出存活对象后,会将它们从 from 复制到 to 区域,复制的过程中自然完成了碎片整理

        3.4复制完成后,交换 from 和 to 的位置即可。

三、四种引用

        总的来说,强引用是最常见的引用类型,只有在不再被引用时才会被回收;软引用在内存不足时会被回收;弱引用在下一次垃圾回收时会被回收;虚引用在对象被回收时会被放入引用队列中,需要手动清除。根据不同的需求和场景,可以选择合适的引用类型来管理对象的生命周期。

(一)强引用:

        普通变量赋值即为强引用,如 A a = new A();通过 GC Root 的引用链,如果强引用不到该对象,该对象才能被回收。

(二)软引用:

        例如:SoftReference a = new SoftReference(new A());如果仅有软引用该对象时,首次垃圾回收不会回收该对象,如果内存仍不足,再次回收时才会释放对象;软引用自身需要配合引用队列来释放,典型例子是反射数据。

(三)弱引用:

        例如:WeakReference a = new WeakReference(new A());如果仅有弱引用引用该对象时,只要发生垃圾回收,就会释放该对象,弱引用自身需要配合引用队列来释放,典型例子是 ThreadLocalMap 中的 Entry 对象。

(四)虚引用:
  1. 例如: PhantomReference a = new PhantomReference(new A(), referenceQueue);

  2. 必须配合引用队列一起使用,当虚引用所引用的对象被回收时,由 Reference Handler 线程将虚引用对象入队,这样就可以知道哪些对象被回收,从而对它们关联的资源做进一步处理

  3. 典型例子是 Cleaner 释放 DirectByteBuffer 关联的直接内存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/548972.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS NEXT应用开发之SideBarContainer侧边栏淡入淡出动效实现案例

介绍 在2in1或平板上,群聊侧边栏是一种较为常用的功能,虽然HarmonyOS已经具备了基本的动效,但是部分情况下开发者可能有定制侧边栏动效的需求,本例主要介绍了如何基于显式动画实现侧边栏的淡入淡出动效。 效果图预览 使用说明&a…

Linux-多线程2 ——线程等待、线程异常、线程退出、线程取消和线程分离

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、线程间的全局变量共享__thread 修饰全局变量 二、线程等待pthread_self和tid 三、线程异常四、线程退出五、线程取消六、线程分离 一、线程间的全局变量共享 上…

第四百一十回

文章目录 1. 概念介绍2. 方法与细节2.1 获取方法2.2 使用细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取当前系统语言"相关的内容,本章回中将介绍如何获取时间戳.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…

Pytorch基础-汇总

本教程翻译自微软教程:https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/ 初次编辑:2024/3/1;最后编辑:2024/3/4 本教程包含以下内容: 介绍pytorch基础和张量操作介绍数据集介绍归一化介绍构…

Navicat16安装时报错记录

1.安装过程中一定要断网 2.安装好后,先不要直接打开客户端,应该先打开激活破解软件,如下: 选择HOSTS--》再Patch-->是,然后生成注册码,打开客户端正常执行即可

二蛋赠书十八期:《一本书讲透Elasticsearch:原理、进阶与工程实践》

Elasticsearch 是一种强大的搜索和分析引擎,被广泛用于各种应用中,以其强大的全文搜索能力而著称。 不过,在日常管理 Elasticsearch 时,我们经常需要对索引进行保护,以防止数据被意外修改或删除,特别是在进…

leetcode刷题日记之最长的有效括号

题目描述 解题思路 首先想到的就是所有的合法的有效括号,必然是用到栈的结构,结果直接提交显示失败,这样求的是全部的合法的字符串,而题目要求的是子串的合法的括号的最大长度。这时候采用的另一种入队方式,就是当遇到…

从零开始学习在VUE3中使用canvas(二):fillStyle(填充样式)

一、fillStyle概念 在canvas中我们可以用fillStyle定义接下来的图像的样式&#xff0c;默认为黑色#000。 我们可以使用纯色、渐变、和纹理&#xff08;例如图片&#xff09;进行填充&#xff0c;来达到自己想要的效果。 二、代码 <template><div class"canva…

8.6 Springboot项目实战 Spring Cache注解方式使用Redis

文章目录 前言一、配置Spring Cache1. @EnableCaching2. 配置CacheManager3. application.properties配置二、使用注解缓存数据1. 使用**@Cacheable** 改造查询代码2. 使用**@CacheEvict** 改造更新代码前言 在上文中我们使用Redis缓存热点数据时,使用的是手写代码的方式,这…

win下 VirtualBox 自动启动脚本脚本

文章目录 一、找到VBoxManage二、测试脚本1、打开cmd2、输入命令 (直接把上面找到的VBoxManage.exe 拖入到cmd中&#xff0c;这样就不用输入路径了)3、效果展示 比如虚拟机中的系统名称叫“centos-mini” 三、设置自动启动脚本1、复制刚才测试好的命令到新建文本中2、修改文本名…

谷歌google adsense广告申请提示:网站已下线或无法访问

自己在运营网站时&#xff0c;想在网站上挂google adsense广告&#xff0c;但是申请很多次&#xff0c;收到的邮件都是您需要先纠正一些问&#xff0c;登陆google adsense后台显示&#xff0c;网站已下线或无法访问。 重新申请多次问题依旧&#xff0c;我在想为什么国外无法访…

轻松打造完美原型:9款在线工具推荐

早年&#xff0c;UI设计师选择的工具有限&#xff0c;功能相对单一&#xff0c;大多数在线原型设计工具都是国外的&#xff0c;语言和网络都增加了设计工作的负担。如今&#xff0c;国内外有许多在线原型设计工具&#xff0c;不仅可以在浏览器上使用&#xff0c;而且还具有团队…