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类来提供虚引用. 

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

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

相关文章

疾控中心的污水采样瓶用的是什么材质

疾控中心的污水采样瓶采用的材质是聚乙烯或聚丙烯塑料。这种材质的污水采样瓶具有耐腐蚀、耐高压、无毒无味、重量轻、易于携带等优点。此外,这种材质的污水采样瓶还可以在高温下消毒,不会变形或破裂。 疾控中心的污水采样瓶通常有不同的容积和形状&…

Redis 缓存数据库

redis 中文网 http://www.redis.cn/ redis.net.cn 两种数据库阵营 1.关系型数据库 MySQL Oracle DB2 SQL Server 等基于二维表结构存储数据的文件型磁盘数据库 缺点: 因为数据库的特征是磁盘文件型数据库, 就造成每次查询都有IO操作, 海量数据查询速度较慢 2.NoSQL数据库 …

【亚马逊云科技】通过Amazon CloudFront(CDN)快速访问资源

文章目录 前言一、应用场景二、【亚马逊云科技】CloudFront(CDN)的优势三、入门使用总结 前言 前面有篇文章我们介绍了亚马逊云科技的云存储服务。云存储服务主要用于托管资源,而本篇文章要介绍的CDN则是一种对托管资源的快速访问服务&#…

137 Linux 系统编程14 ,gdb对于父子进程的调试,exec函数族原理分析

一 gdb 对于 父子进程的 调试 使用gdb调试的时候,gdb只能跟踪一个进程。可以在fork函数调用之前,通过指令设置gdb调试工具跟踪父进程或者是跟踪子进程。默认跟踪父进程。 set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程。 set follow-…

深度学习--神经网络基础

神经网络 人工神经网络( Artificial Neural Network , 简写为 ANN )也简称为神经网络( NN ),是一种模仿生物神经网络结构和 功能的计算模型 。人脑可以看做是一个生物神经网络,由众多的 神经元…

时间管理大师速成(程序员版)

01 时间管理的重要性 管理时间有几个主要的原因: 时间和生活质量:时间是我们拥有的最宝贵的资源之一,管理好时间会直接影响我们的生活质量。高效的时间管理可以让我们开展日常活动,实现目标,并拥有休闲和休息的时间。 …

OpenMLDB v0.8.5 发布:认证功能完善,安全升级全面实施

发布日期 27 February 2024 Release note https://github.com/4paradigm/OpenMLDB/releases/tag/v0.8.5 Highlights 增加 Apache Iceberg 离线存储引擎集成,支持导入数据,导出特征计算数据等功能,进一步加强生态集成。增加标准 SQL 语法…

Linux alias命令(为复杂命令创建别名,其中命令可带选项或参数)

文章目录 Mastering the Linux alias Command(精通Linux的alias命令)1. Understanding the alias Command(理解alias命令)示例Ubuntu20.04 arm操作系统OpenEuler20.03 arm操作系统 2. Basic Usage of alias(alias的基本…

抖音商品详情数据API接口采集(属性,主图,价格,sku等)item_get-获得抖音商品详情

item_get-获得抖音商品详情 douyin.item_get 公共参数 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥WeChat18305163218api_nameString是API接口名称(包括在请求地址中)[item_search,i…

什么是企业架构?企业架构有什么具体作用?实施企业架构的条件是什么?

(一)什么是企业架构 企业架构是一种系统思考的方法,旨在帮助企业理解、设计和管理复杂的业务和技术系统。 企业架构的核心概念是将企业视为一个由多个相互关联的组成部分构成的系统,这些组成部分包括业务、数据、应用和技术&…

python自动化管理和zabbix监控网络设备(无线AC控制瘦ap配置部分)

目录 前言 拓扑 一、AC-SW1 二、Core-sw1 三、Core-sw2 四、汇聚层 五、AC1 六、SW1-6 七、DMZ区域 前言 具体原理和操作可以访问我的主页视频 白帽小丑的个人空间-白帽小丑个人主页-哔哩哔哩视频 拓扑 一、AC-SW1 sys sysname AC-SW1 vlan batch 100 200 210 220 2…

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

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