Java对象垃圾回收调用,JVM垃圾回收之哪些对象可以被回收

1.背景

Java语言相比于C和C++,一个最大的特点就是不需要程序员自己手动去申请和释放内存,这一切交由JVM来完成。在Java中,运行时的数据区域分为程序计数器、Java虚拟机栈、本地方法栈、方法区和堆。其中,程序计数器、虚拟机栈和本地方法栈是线程私有的,线程销毁后自动释放。垃圾回收的行为发生在堆和方法区,主要是堆,而堆中存储的主要是对象。那么自然而然地就会有这么几个问题,哪些对象可以被回收?通过什么方式回收?本文主要探讨第一个问题,以及JVM对Java中几种引用的回收策略。

2.如何判断一个对象是否可以被回收 2.1 引用计数法

主要思想是:给对象添加一个引用计数器,这个对象被引用一次,计数器就加1;不再引用了,计数器就减1。如果一个对象的引用计数器为0,说明没有人使用这个对象,那么这个对象就可以被回收了。这种方法实现起来比较简单,效率也比较高,大多数情况下都是有效的。但是,这种方法有一个漏洞。比如A.property = B,B.property = A,A和B两个对象互相引用,并且没有其他对象引用A和B。按照引用计数法的思想,A和B对象的引用计数器都不为0,都不能被释放,但实际情况是A和B已经没人使用他们了,这就造成了内存泄漏。所以,引用计数法虽然实现简单,但并不是一个完美的解决方案,实际中的Java也没有采用它。

2.2 可达性分析算法

主要思想是:首先确定确定一系列肯定不能被回收的对象,即GC Roots。然后,从这些GC Roots出发,向下搜索,去寻找它直接和间接引用的对象。最后,如果一个对象没有被GC Roots直接或间接地引用,那么这个对象就可以被回收了。这种方法可以有效解决循环引用的问题,实际中Java也是采用这种判断方法。那么问题来了,哪些对象可以作为GC Roots呢?这里可以使用MAT工具进行观察。运行下面的demo:

import java.util.concurrent.TimeUnit; public class GCRootsTest { public static void main(String[] args) throws InterruptedException { Object o = new Object(); TimeUnit.SECONDS.sleep(100); }}

主线程sleep的时候,在terminal窗口执行jmap -dump:format=b,live,file=heapdump.bin 2872命令,生成堆转储快照dump文件,其中2872是进程id,可以使用jps命令查看。然后使用MAT工具打开dump文件,可以很明显地看到一共有四类对象可以作为GC Roots,下面详细介绍下。

dd0e75baf1be44ff182e9248560fda26.png

第一类,系统类对象(System Class)。比如,java.lang.String的Class对象,这个也很好理解,如果这些核心的系统类对象被回收了,程序就没办法运行了。

第二类,native方法引用的对象。

3946ebf5d0bf6608ef179e976f4b1e0d.png

第三类,活动线程中正在引用的对象。可以看出,代码中变量o指向的Object对象可以被当作GC Roots。

1fd9df3bf2318b0d25d95130ed175240.png

第四类,正在加锁的对象。

4633d46674c8122fed77fd97b80f41b9.png

3.Java中的几种引用

在可达性分析算法中,判断一个对象是不是可以被回收,主要看从GC Roots出发是否可以找到一个引用指向该对象。java中的引用一共有四种,按照引用的强弱依次为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)。这样就可以对不同引用指向的对象采取不同的回收策略。比如一个强引用指向一个对象,那么这个对象肯定不会被回收,哪怕发生OOM。而对于弱引用指向的对象,只要发生垃圾回收,该对象就会被回收。下面详细介绍下不同引用的用法。

3.1强引用

所谓强引用,就是平时使用最多的,类似于Object obj = new Object()的引用。垃圾回收器永远不会回收被强引用指向的对象。

3.2软引用

软引用,在Java中使用SoftReference类来实现软引用。在下面的代码中,softReference作为软用指向一个Object对象,而otherObject变量可以通过软引用的get方法间接引用到Object对象。

public static void main(String[] args) { // 软引用 SoftReference

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

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

相关文章

hp

命令组成hpacucli [parametervalue] 查看: 查看所有控制器状态 hpacucli ctrl all show 查看slot 0阵列信息详细状态 (可以查看物理磁盘和逻辑磁盘的对应关系)1)hpacucli ctrl slot0 show config detail2)hpacucli ct…

报告|机器人行业深度报告:机器人产业价值与回报相关度分析

来源:机器人大讲堂2009~2018年中国工业机器人保有量在全球保有量的占比稳步提升。据IFR数据,截止2018年底,中国工业机器人保有量达到64.94万台,全球占比为26.97%。2013~2018年间中国新增工业机器人中国产品…

python 笔记本_Python笔记本

Python 的主提示符( >>> )和次提示符( ... )。主提示符是解释器告诉你它在等你输入下一个语句,次提示符告诉你解释器正在等待你输入当前语句的其它部分。下划线(_)在解释器中有特别的含义,表示最后一个表达式的值。所以上面的代码执行之后,下划线变量会包含字符串In […

百度面试 php后端,2019.7最惨的三次面试经历-----百度PHP实习生面经

一、百度--文娱架构部一面 半小时 前台小姐姐很漂亮都是根据简历上写的来问的,说几个知道的排序算法,讲讲堆排序,堆是什么结构,我说堆类似于完全二叉树,讲讲完全二叉树和满二叉树的区别,手撕快速排序&#…

netty客户端源码

随笔记录。 //创建一个ChannelFactory(客户端代码) ChannelFactory factory new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); // NioClientSocketChannelFactory构造方法 public NioClientSoc…

汉字的ascii码值范围_ASCII代码

同学们,我们都知道计算机只能接受二进制信息,很显然直接给出英文的ABCD计算机并不认识,那为何敲击键盘屏幕就可以显示出对应的字符呢?为了解决这个问题,计算机采用一套编码,每个编码都是唯一的,…

从ICLR提交论文看机器学习的趋势和风口

大数据文摘出品来源:deepsense2013年才举办第一届的ICLR(The International Conference on Learning Representations)发展迅猛,如今已成为是最重要的国际机器学习会议之一,甚至可以和ICML,NeurIPS和CVPR这…

php 登录安全认证,介绍几种常用的web安全认证方式

本文为大家介绍了五种常用的web安全认证方式,具有一定的参考价值,希望能对大家有所帮助。1、Http Basic Auth这是一种最古老的安全认证方式,这种方式就是简单的访问API的时候,带上访问的username和password,由于信息会…

日期选择控件-laydate

laydate控件非常简单易用&#xff0c;只需要调用一个个函数就可以轻松实现日期时间选择。 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%><%String path request.getContextPath();String basePath request.getS…

python decorator. decorator_Python中decorator使用实例

在我以前介绍 Python 2.4 特性的Blog中已经介绍过了decorator了&#xff0c;不过&#xff0c;那时是照猫画虎&#xff0c;现在再仔细描述一下它的使用。关于decorator的详细介绍在 Python 2.4中的Whats new中已经有介绍&#xff0c;大家可以看一下。如何调用decorator基本上调用…

php文件上传到虚拟主机,php源码上传到虚拟主机(php源码上传到服务器)

php网站的源码在上传到虚拟主机之前&#xff0c;需要做什么修改本人小白&#xff0c;只知道需。这个啊&#xff0c;倒是简单&#xff0c;你下载个ftp软件&#xff0c;登陆上传即可&#xff0c;不过要注意传对目录&#xff0c;一般的虚拟主机都有好几目录的&#xff0c;要传合适…

这个“大脑”收获一份大奖!

来源&#xff1a;新华社第17届亚洲-太平洋通讯社组织&#xff08;亚通组织&#xff09;全体大会8日在韩国首尔闭幕。大会颁发了亚通组织卓越通讯社品质奖&#xff0c;中国新华通讯社与越南通讯社分别获奖。这是亚通组织主席、阿塞拜疆国家新闻社社长阿斯兰阿斯兰诺夫&#xff0…

arm-linux-gnueabi和arm-linux-gnueabihf 的区别

转载整理自&#xff1a;http://www.cnblogs.com/xiaotlili/p/3306100.html 一、 什么是ABI和EABI1 、ABI ABI(二进制应用程序接口-Application Binary Interface (ABI) for the ARM Architecture)在计算机中&#xff0c;应用二进制接口描述了应用程序&#xff08;或者其他类型&…

检查用户名是否存在的servlet代码怎么写_Servlet详解!!!

1 掌握 请求转发2 掌握 请求重定向3 掌握cookie1. 请求转发介绍(1) 为什么需要请求转发?以此请求的处理需要多个Servlet的联动操作,第一个Servlet需要用到其他Servlet已经声明的逻辑处理代码(2) 请求转发的本质是什么&#xff1f;其实就是在一个Servlet中调用其他的Servlet2. …

学习人工智能必须攻克三道门槛:数学基础、英语水平与编程技术

来源&#xff1a;搜狐广义的说&#xff0c;人工智能包含诸多不同方法&#xff0c;其主旨是让程序像一个智能体一样解决问题。机器学习是实现人工智能的一种方法&#xff0c;它不完全依靠预先设计&#xff0c;而是从数据中进行总结&#xff0c;达到模拟记忆、推理的作用。包括诸…

oracle 批量 重建索引,Oracle重建索引Shell脚本、SQL脚本分享

索引是提高数据库查询性能的有力武器。没有索引&#xff0c;就好比图书馆没有图书标签一样&#xff0c;找一本书自己想要的书比登天还难。然而索引在使用的过程中&#xff0c;尤其是在批量的DML的情形下会产生相应的碎片&#xff0c;以及B树高度会发生相应变化&#xff0c;因此…

pandas 学习(二)—— pandas 下的常用函数

import pandas as pd; 1. 数据处理函数 pd.isnull()/pd.notnull()&#xff1a;用于检测缺失数据&#xff1b;2. 辅助函数 pd.to_datetime()3. Series 与 DataFrame 的成员函数 drop(labels, axis0, levelNone, inplaceFalse, errors’raise’) 注意第一个参数&#xff08;label…

python中set index_python中set基础应用

set:类似dict,是一组key的集合&#xff0c;不存储value本质是无序和无重复元素的集合#创建#创建set需要一个list或者tuple或者dict作为输入集合s1set({1,2,3,4,5})s2set({1,2,2,5,3,3,5})s3set({1:"123",2:"daf"})print(s1)#{1, 2, 3, 4, 5}print(s2)#{1, …

【智能驾驶】自动驾驶深度感知技术对车和行人的检测

来源&#xff1a;小马智行第二场技术沙龙今天我主要想分享自动驾驶感知技术在探索的过程中&#xff0c;采用的传统方法和深度学习方法。传统方法不代表多传统&#xff0c;深度学习也不代表多深度。它们有各自的优点&#xff0c;也都能解决各自的问题&#xff0c;最终希望将其结…

matlab读取其他位置,将文件的数据读取到matlab中,进行编辑,然后将其保存到其他位置...

将文件的数据读取到matlab中&#xff0c;进行编辑&#xff0c;然后将其保存到其他位置 我有一个名为EXP1_SQ1_Template.txt的文件。这是一个简单的文本文件&#xff0c;包含以下8行&#xff1a;LOAD BOX 1 SUBJ M1_299633_D295158_JUN191910_Aut_ERROR2 EXPT St(m)_Se(n)_Rat1 …