JVM(3)

垃圾回收(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类来提供虚引用. 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hack The Box-Fawn

目录 TASK 1 TASK 2 TASK 3 TASK 4 TASK 5 TASK 6 TASK 7 TASK 8 TASK 9 TASK 10 TASK 11 SUBMIT FLAG TASK 1 What does the 3-letter acronym FTP stand for?File Transfer Protocol (文件传输协议 FTP)TASK 2 Which port does the FTP service listen on usual…

腾讯云优惠券领取入口、云服务器优惠、领取方法及使用教程

腾讯云服务器多少钱一年?62元一年起,2核2G3M配置,腾讯云2核4G5M轻量应用服务器218元一年、756元3年,4核16G12M服务器32元1个月、312元一年,8核32G22M服务器115元1个月、345元3个月,腾讯云服务器网txyfwq.co…

国产新能源车确立全球领先地位 珠光材料等上游产业链亦乘风而起

农历新年伊始,中国新能源汽车的老大哥比亚迪率先开启了一波降价狂潮,比亚迪秦PLUS荣耀版、驱逐舰05荣耀版正式上市,相较于上一版本冠军版车型,两款新版本车型价格均下降了2万元至7.98 万元起售,堪称王炸出牌。当天&…

Python教程59:海龟画图turtle满屏飘字(飞雪连天射白鹿,笑书神侠倚碧鸳)

---------------turtle源码集合--------------- Python教程91:关于海龟画图,Turtle模块需要学习的知识点 Python教程51:海龟画图turtle画(三角形、正方形、五边形、六边形、圆、同心圆、边切圆,五角星,椭…

Java核心API-反射

反射 文章目录 反射前言一、反射概念二、反射与Class类获取Class对象方式 三、反射访问构造方法1、获取包名2、获取类名3、获取父类名称4、获取接口5、获取类中构造方法1)获取所有的构造方法2)获取public修饰的构造方法3)获取private修饰的构…

基于java SSM springboot动物检疫信息管理系统设计和实现

基于java SSM springboot动物检疫信息管理系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末…

AI:145-智能监控系统下的行人安全预警与法律合规分析

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

milvus upsert流程源码分析

milvus版本:v2.3.2 整体架构: Upsert 的数据流向: 1.客户端sdk发出Upsert API请求。 import numpy as np from pymilvus import (connections,Collection, )num_entities, dim 4, 3print("start connecting to Milvus") connections.connect("default",…

代码随想录刷题训练营day25:LeetCode(216)组合总和III、LeetCode(17)电话号码的字母组合

代码随想录刷题训练营day25:LeetCode(40)组合总和 II、LeetCode(216)组合总和III、LeetCode(17)电话号码的字母组合 LeetCode(40)组合总和 II 题目 代码 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util…

lv19 多态 4

1 虚函数 虚函数&#xff08; 基类指针可指向派生类对象&#xff0c; 动态联编&#xff09; 先看示例&#xff0c;不加virtual&#xff0c;不认对象认指针。 #include <iostream>using namespace std;class A{ public:A(){ }~A(){ }void show(){cout<<"AAA…

火灾安全护航:火灾监测报警摄像机助力建筑安全

火灾是建筑安全中最常见也最具破坏力的灾难之一&#xff0c;为了及时发现火灾、减少火灾造成的损失&#xff0c;火灾监测报警摄像机应运而生&#xff0c;成为建筑防火安全的重要技术装备。 火灾监测报警摄像机采用高清晰度摄像头和智能识别系统&#xff0c;能够全天候监测建筑内…

LeetCode #104 二叉树的最大深度

104. 二叉树的最大深度 题目 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输出&#xff1a;2 分析 …

程序员缺乏经验的 7 种表现!

程序员缺乏经验的 7 种表现&#xff01; 一次性提交大量代码 代码写的很烂 同时开展多项工作 性格傲慢 不能从之前的错误中学到经验 工作时间处理私人事务 盲目追逐技术潮流 知道这些表现&#xff0c;你才能在自己的程序员职业生涯中不犯相同的错误。 软件行业的工作经…

Zookeeper基础入门-2【ZooKeeper 分布式锁案例】

Zookeeper基础入门-2【ZooKeeper 分布式锁案例】 四、ZooKeeper-IDEA环境搭建4.1.环境搭建4.1.1.创建maven工程&#xff1a;zookeeper4.1.2.在pom文件添加依赖4.1.3.在项目的src/main/resources 目录下&#xff0c;新建文件为“log4j.properties”4.1.4.创建包名com.orange.zk …

springboot 注解属性转换字典

1.注解相关功能实现 定义属性注解 import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.vehicle.manager.core.serializer.DicSerializer;import java.lang.annotation.*;/*** a…

c++学习记录 deque容器—数据存取

函数原型&#xff1a; at(int idx); //返回索引idx所指的数据operator[]; //返回索引idx所指的数据front(); //返回容器中第一个数据元素back(); //返回容器中最后一个数据元素 #include<iostream> using nam…

websocket在django中的运用

14-2 聊天室实现思路&#xff1a;轮训、长轮训、websocket_哔哩哔哩_bilibili 参考大佬的B站学习笔记 https://www.cnblogs.com/wupeiqi/p/6558766.html 参考博客 https://www.cnblogs.com/wupeiqi/articles/9593858.html 参考博客 http协议: 是短连接&#xff0c;无状态…

【LeetCode】每日一题:使二叉树所有路径值相等的最小代价

该题采用自底向上的思路的话&#xff0c;很容易想到使用贪心的思想&#xff0c;但是如何进行具体操作却有些难度。 这里补充一个重要的结论&#xff1a;二叉树的数组形式中&#xff0c;第i个节点的父节点是i/2&#xff1b;接下来只需要让自底向上让每个路径上的代价保持最低限…

Python实现自动检测设备连通性并发送告警到企业微信

背景&#xff1a;门禁机器使用的WiFi连接&#xff0c;因为某些原因会不定期自动断开连接&#xff0c;需要人工及时干预&#xff0c;以免影响门禁数据同步&#xff0c;故写此脚本&#xff0c;定时检测门禁网络联通性。 #首次使用要安装tcping模块 pip install tcpingfrom tcpin…

Jupyter Notebook 下载+简单设置

这里写目录标题 1. Jupyter Notebook安装2.切换打开别的盘3. 创建代码文件4.为jupyter notebook添加目录 (Jupyter安装拓展nbextensions)step1&#xff1a;安装命令step2&#xff1a;用户配置step3&#xff1a;上述过程均完成后&#xff0c;打开jupyter notebook就会发现界面多…