JVM(3)

news2025/2/28 5:14:09

垃圾回收(GC)相关

在C/C++中,当我们使用类似于malloc的内存开辟,还需要手动释放内存空间,这样的机制在使用时给我们造成了诸多不便,但在Java中,有垃圾回收这样的机制,这就是指:我们不再需要手动释放,程序会自动判定,某个内存空间是否可以继续使用,如果内存不使用了,就会自动释放掉.

上面讲了Java的各个区域,对于程序计数器,虚拟机栈,本地方法栈这三部分而言,其生命周期与线程有关,随线程而生,随线程而灭.并且这三个区域的内存分配与回收具有确定性,因为当方法结束或者现车给结束时,内存就自然跟着线程回收了. 在元数据区/方法区中:一般不需要GC:一般都是类加载,而不是类卸载.  而堆是GC的主战场.更准确的是回收对象.每次回收时,释放若干对象(单位都是对象).

Java堆中存放着几乎所有的对象实例,垃圾回收器在堆进行垃圾回收前,首先要判断这些对象哪些还存活,哪些已经"死去",然后后续才是清理的过程,判断对象是否"死"有如下几种算法:

内存vs对象

在Java中,所有的对象都是要存储在内存中的(也可以说内存中存储的是一个对象),因此我们将内存回收,也可以叫死亡对象的回收.

识别出垃圾:确定这个对象后续是否会用(在Java中,使用对象,一定要通过引用的方式使用(当然,有一个例外=>那就是类似于new MyThread().start这样的匿名对象,这里的代码执行完,对应的对象就会当作为垃圾))

死亡对象的判断算法

引用技术算法

引用计数描述的算法为:

给对象增加一个计数器,每当有一个地方引用它时,计数器就+1;当引用失效时,计数器就-1;任何时刻的计数器为0的对象就是不能再被使用时,即对象已死.

引用计数法实现简单,判定效率也高,在大部分情况下都是一个不错的算法,比如Python语言就采用引用计数法进行内存管理.

但是引用计数算法也出现了两个关键的问题

1.消耗了额外的内存空间.

如果要给每个对象都安排一个计数器(如果计数器按照两个字节算).如果整体程序中的对象很多,总的消耗空间也多,总的消耗空间也多.尤其是每个对象中的体积比较小(假设每个对象四个字节).计数器所消耗的空间,已经达到对象空间的一半.(类似于公摊面积,十分难造). 

2.循环引用

范例:观察循环引用问题

public class Test1 {
    public Object instance = null;
    private static int _1MB = 1024 * 1024;
    private byte[] bigSize = new byte[2 * _1MB];
    public static void testGC() {
        Test1 test1 = new Test1();
        Test1 test2 = new Test1();
        test1.instance = test2;
        test2.instance = test1;
        test1 = null;
        test2 = null;
        //强制jvm进行回收
        System.gc();
    }

    public static void main(String[] args) {
        testGC();
    }
}

 [GC (System.gc()) 6092K->856K(125952K), 0.0007504 secs]

从结果可以看出,GC日志包含"6092K->856K(125952K)",意味着虚拟机并没有因为这两个对象互相引用就不回收它们.即JVM并不使用引用计数法来判断对象是否存活.

 可达性分析算法(JVM是用这个)

本质上是用时间换空间,相比于引用计数,需要消耗更多的额外时间.但总体来说,是可控的,不会产生"循环引用问题".

此算法的核心思想为:在写代码时,会定义很多变量.比如,栈上的局部变量/方法中的静态类型变量/常量池中引用对象.  就以这一系列称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索(遍历),搜索走过的路径称为"引用链",当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达时),证明此对象是不可用的.  (所有能被访问到的对象,自然就不是垃圾了,剩下的遍历一圈,也访问不到的对象,就是垃圾).

JVM中存在扫描线程,会不停尝试对代码中已有的这些变量,进行遍历,尽可能多的去访问对象.

JVM自身知道有哪些对象,通过可达性的分析的遍历,把可达对象标出来,剩下的自然是不可达.

对象Object5-Object7之间虽然彼此还有关联,但是它们到Roots是不可达的,因此它们会被判定为可回收对象. 

在Java语言中,可作为GC Roots的对象包含以下几种:

1.虚拟机栈(栈帧中的本地变量表)中引用的对象;

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

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

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

从上面可以看出"引用"的功能,除了最早我们使用它(引用)来查找对象,现在我们可以使用"引用"来判断死亡对象了.所以在jdk1.2时,Java对引用概念做了扩充,将引用分为强引用,软引用,弱引用和虚引用四种,这四种的强度依次递减.

1.强引用:强引用指的是在程序代码中普遍存在的,类似于"Object obj = new Object()"这类的引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象实例.

2.软引用:软引用是用来描述一些还有用但是不是必须的对象.对于软引用关联着的对象,在系统将要发生内存溢出之前,会把这些对象列入回收范围之中进行第二次回收.如果这次回收还是没有足够的内存,才会抛出内存溢出异常.在JDK1.2之后,提供了SoftReference类来实现软引用

3.弱引用:弱引用也是用来描述非必须对象的.但是它的强度要弱于软引用.被弱引用关联的对象只能生存到下一次垃圾回收发生之前.当垃圾回收器开始进行工作时,无论当前内容是否够用,都会回收掉只被弱引用关联的对象.在JDK1.2之后提供了WeakReference类来进行弱引用.

4.虚引用:虚引用也被称为幽灵引用或者幻影引用,它是最弱的一种引用关系.一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例.为一个对象设置虚引用的唯一目的就是能在这个对象被收集器回收时收到一个系统通知.在JDK1.2之后,提供了PhantonReference类来提供虚引用. 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(转载)SpringCloud 微服务(三)-Seata解决分布式事务问题

ps:这个原文写的很好,怕后续这个地址失效,备份一个留着自己学习 转自:SpringCloud 微服务(三)-Seata解决分布式事务问题_seata 黑马 代码-CSDN博客 看完了黑马程序员的免费课程,感觉受益匪浅,…

堆排序C++(Acwing)

代码&#xff1a; #include <iostream> #include <algorithm>using namespace std;const int N 100010;int n, m; int h[N], cnt;void down(int u) {int t u;if(u * 2 < cnt && h[u * 2] < h[t]) t u * 2;if(u * 2 1 < cnt && h[u *…

【架构之路】糟糕程序员的20个坏习惯,切记要改掉

文章目录 强烈推荐前言&#xff1a;坏习惯:总结&#xff1a;强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 前言&#xff1a; 优秀的程序员…

【重要公告】BSV区块链协会全新推出“网络访问规则NAR”

​​发表时间&#xff1a;2024年2月15日 BSV区块链协会正式宣布已为BSV区块链推出一套全新的网络访问规则&#xff08;Network Access Rules&#xff0c;以下简称“NAR”&#xff09;。 NAR是一整套规则&#xff0c;用于规范BSV协会与BSV网络节点之间的关系。它基于比特币最初…

Unity 常用操作

2D素材网站 https://craftpix.net/ https://itch.io/game-assets/tag-2d/tag-backgrounds 3D素材资源网址 https://www.mixamo.com/#/ 场景常用操作&#xff1a; 快捷键&#xff1a;QWER Q&#xff1a;Q键或鼠标中键&#xff0c;可以拉动场景。 W&#xff1a;选中物体后&…

雾锁王国服务器要开服务器吗?

雾锁王国要开服务器吗&#xff1f;可以使用官方服务器&#xff0c;也可以自己搭建多人联机服务器&#xff0c;更稳定不卡&#xff0c;畅玩开黑。阿腾云分享atengyun.com给大家目前阿里云和腾讯云均提供雾锁王国服务器和一键搭建程序&#xff0c;成本26元即可搭建一台自己的雾锁…

小白水平理解面试经典题目leetcode 606. Construct String from Binary Tree【递归算法】

Leetcode 606. 从二叉树构造字符串 题目描述 例子 小白做题 坐在自习室正在准备刷题的小白看到这道题&#xff0c;想想自己那可是没少和白月光做题呢&#xff0c;也不知道小美刷题刷到哪里了&#xff0c;这题怎么还没来问我&#xff0c;难道是王谦谦去做题了&#xff1f; 这…

换根DP,LeetCode 2581. 统计可能的树根数目

目录 一、题目 1、题目描述 2、接口描述 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 Alice 有一棵 n 个节点的树&#xff0c;节点编号为 0 到 n - 1 。树用一个长度为 n - 1 的二维整数数组 edges 表示&#xff0c;其中 edges[…

特征值和特征向量及其在机器学习中的应用

特征值和特征向量是线性代数中的概念&#xff0c;用于分析和理解线性变换&#xff0c;特别是由方阵表示的线性变换。它们被用于许多不同的数学领域&#xff0c;包括机器学习和人工智能。 在机器学习中&#xff0c;特征值和特征向量用于表示数据、对数据执行操作以及训练机器学…

MVCC【重点】

参考链接 [1] https://www.bilibili.com/video/BV1YD4y1J7Qq/?spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source0cb0c5881f5c7d76e7580fbd2f551074 [2]https://www.cnblogs.com/jelly12345/p/14889331.html [3]https://xiaolincoding.com/mysql…

第十三篇【传奇开心果系列】Python的文本和语音相互转换库技术点案例示例:Microsoft Azure的Face API开发人脸识别门禁系统经典案例

传奇开心果博文系列 系列博文目录Python的文本和语音相互转换库技术点案例示例系列 博文目录前言一、实现步骤和雏形示例代码二、扩展思路介绍三、活体检测深度解读和示例代码四、人脸注册和管理示例代码五、实时监控和报警示例代码六、多因素认证示例代码七、访客管理示例代码…

自然语言处理(NLP)中NER如何从JSON数据中提取实体词的有效信息

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

4.5.CVAT——视频标注的详细步骤

文章目录 1. 跟踪模式&#xff08;基础&#xff09;2. 跟踪模式&#xff08;高级&#xff09;3. 带多边形的轨迹模式 追踪模式Track mode &#xff08;视频标注使用&#xff09;——类似pr的动画效果 1. 跟踪模式&#xff08;基础&#xff09; 使用示例&#xff1a; 为一系列…

input css padding

这样控件会跑出外套控件在HTML JSP里面是经常出现的。但有些外国adobe的as控件不存在这种情况&#xff0c;这是因为内层控件定义的时候不能超出外层控件的范围。 修改下&#xff1a;去掉原来css padding&#xff0c;然后加上宽度和高度

electron安装最后一部卡住了?

控制台如下错误 不是的话基本可以划走了 这个很可能是镜像出现问题了&#xff0c;不一定是npm镜像 打开npm的配置文件添加下述 electron_mirrorhttps://cdn.npmmirror.com/binaries/electron/ electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-build…

一. demo

1. 舞台-场景-控件 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.stage.Stage;import java.util.Arrays;public class Main e…

Stable Diffusion 3:创新技术引领未来趋势

文章目录 Stable Diffusion 3&#xff1a;创新技术引领未来趋势摘要Stable Diffusion 3 的发布技术发展方向行业影响总结&#xff1a; Stable Diffusion 3&#xff1a;创新技术引领未来趋势 摘要 在当今快速发展的技术领域&#xff0c;Stable Diffusion 3以其卓越的稳定性和创…

FPGA-学会使用vivado中的存储器资源RAM(IP核)

问题 信号源(例如ADC)以1us一个的速率产生12位的数据现要求获得连续1ms内的数据,通过串口以115200的波特率发到电脑。 分析 数据量是1000个 数据速率不匹配 数据内容未知 数据总数据量有限 数据的使用速度低于数据的产生速度 数据生产和消耗的位宽 数据量相对较…

Spring基础——Spring简介

目录 Spring简述Spring起源Spring技术核心1. Spring IoC2. Spring AOP3. Spring Framework4. Spring Boot Spring涉及领域 Spring简述 如果想快速上手spring开发的话这边先给出spring的官方文档 官方教程&#xff1a;spring.io guides 中文教程&#xff08;官方镜像&#xff09…

代码随想录算法训练营day29

题目&#xff1a;491_非递减子序列&#xff08;看了题解&#xff09; 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c;递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7]…