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.mzph.cn/news/708916.shtml

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

相关文章

数据抽取平台pydatax介绍--实现和项目使用

数据抽取平台pydatax实现过程中,有2个关键点: 1、是否能在python3中调用执行datax任务,自己测试了一下可以,代码如下: 这个str1就是配置的shell文件 try:result os.popen(str1).read() except Exception as …

【附学习笔记合集】零基础自学网络安全,从入门到精通,还学不会我退出网安圈!

一、自学网络安全学习的误区和陷阱 1.不要试图先以编程为基础的学习再开始学习 我在之前的回答中,我都一再强调不要以编程为基础再开始学习网络安全,一般来说,学习编程不但学习周期长,而且实际向安全过渡后可用到的关键知识并不…

面试经典150题——插入区间

"The future belongs to those who believe in the beauty of their dreams." - Eleanor Roosevelt 1. 题目描述 2. 题目分析与解析 2.1 思路一 解决这个问题的思路是基于区间排序和合并的经典算法。这个问题的关键在于如何处理新区间与现有区间的关系&#xff0c…

测评ONLYOFFICE 8.0版本:办公利器再升级

测评ONLYOFFICE 8.0版本:办公利器再升级 前言注册使用升级功能速览全新外观设计wordexcelPPTPDF 协作功能强化更强大的功能复杂表单的填写 移动端优化结语 前言 随着科技的不断发展,办公软件在提升用户体验和工作效率方面扮演着越来越重要的角色。作为一…

18V/5A桥式驱动芯片-SS6285L兼容替代RZ7889

SS6285L是一款由工采网代理的率能DC双向马达驱动电路芯片;该芯片采用SOP8封装,符合ROHS规范,引脚框架100%无铅;它适用于玩具等类的电机驱动、自动阀门电机驱动、电磁门锁驱动等应用。 (1)产品描述&#xff…

二叉树(C/C++)

本篇将较为详细的介绍二叉树的相关知识,以及二叉树的实现。对于二叉树的相关知识,本篇介绍了其概念、特殊的二叉树、性质还有存储结构。 接着对于实现二叉树的每个函数都有其思路讲解,主要的函数分为:遍历:前中后序遍历…

QT Mingw编译ffmpeg源码以及测试

文章目录 前言下载msys2ysamFFmpeg 搭建编译环境安装msys2安装QT Mingw编译器到msys环境中安装ysam测试 编译FFmpeg 前言 FFmpeg不像VLC有支持QT的库文件,它仅提供源码,需要使用者自行编译成对应的库,当使用QTFFmpeg实现播放视频以及视频流时…

LVS+Keepalived高可用群集

一、Keepalived简介 Keepalived 软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务&…

Vue NextTick工作原理及使用场景

$nextTick的定义及理解: 定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。 所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操…

springboot集成quartz定时任务并接入后台管理系统(copy即用)

说明:项目启动后会根据设置的时间进行执行,业务代码根据自己的需求更改,数据库文件在最后(记得清空数据库哦~)这里需要注意的一点就是className字段表示的是下面的对应的DynamicTask的路径如:com.example.demo.quartz.task.DynamicTask,如有多个定时任务copy并更改Dynam…

团结引擎——DotNet Wasm方案

参考:团结引擎 DotNet WebAssembly(Wasm) 介绍 一、当前编译流程 通过IL2CPP将C#转成C/C;通过Emscripen将C/C转成WebAssembly; 二、 当前存在问题 IL2CPP在处理类似泛型、反射结构时,由于缺少运行时信息,必须全量生…

程序员面试技巧分享

目录 前言1 自我介绍的艺术1.1 简明扼要1.2 强调独特之处1.3 项目亮点突显1.4 结合公司文化 2 技术问题回答的技巧2.1 明确问题理解2.2 结构清晰的回答2.3 强调解决问题的方法 3 团队协作经验的展示3.1 共享成功经验:3.2 强调沟通和解决冲突的能力: 结语…

基础!!!吴恩达deeplearning.ai:卷积层

以下内容有任何不理解可以翻看我之前的博客哦:吴恩达deeplearning.ai专栏 文章目录 回顾——密集层 Dense Layer卷积层 Convolutional Neural Network定义优势具体说明心电图卷积层搭建 到目前为止,你使用的所有神经网络层都是密集层类型,这…

用快代理换Ip爬取boss直聘招聘信息

import requests import random from prettytable import PrettyTable tb PrettyTable() tb.field_names [区域,详情页链接,领导,经营领域,公司名,招聘人数,学历要求,工作经验要求,职位名称,期望薪资,技能要求,福利]headers {"User-Agent":"Mozilla/5.0 (Win…

跳跃游戏Ⅱ

问题 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - …

独立分体式比例阀控制器

比例阀放大器的主要作用是对比例阀进行控制&#xff0c;它产生所需的电信号&#xff0c;并对这些信号进行综合、比较、校正和放大。这样的设备通常包括稳压电源、颤振信号发生器等&#xff0c;以确保比例阀能够准确地响应控制指令。外置模块式的设计使得这种放大器可以方便地与…

windows系统下安装RabbitMQ

一、RabbitMQ安装软件资源准备 因为RabbitMQ是Erlang语言开发的&#xff0c;因此安装Erlang环境在进行安装RbbitMQ的操作&#xff0c;选择两者版本时一定要参考版本的兼容性 1.RabbitMQ国内下载地址&#xff0c;因官网下载比较缓慢&#xff0c;还是国内的稍微快些 https://r…

【日常聊聊】程序员的金三银四

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 方向一&#xff1a;面试技巧分享 方向二&#xff1a;面试题解析 方向三&#xff1a;公司文化解读 方向四&#xff1a;职业规…

Spring篇----第十四篇

系列文章目录 文章目录 系列文章目录前言一、介绍一下 WebApplicationContext二、什么是 spring?三、使用 Spring 框架的好处是什么?四、Spring 由哪些模块组成?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,…

android studio Unable to download file ‘xxx‘ in offline mode.

如果网络连接正常&#xff0c;但是报这个错&#xff0c;说明开启了离线模式&#xff0c;关掉就行了。 "toggle offline mode" 意思是切换到离线模式 点击右上角的Gradle&#xff0c;然后关闭倒数第二个图标。