深入理解JVM(四) -- 垃圾内存回收的判定方法和内容
上一篇文章我们学到了对象在内存中是如何存储的已经是如何被访问的,这篇文章将介绍当内存空间不够时,虚拟机将怎样判定对象可不可以被回收已经哪些地方会发生回收。
垃圾回收主要(不是全部)发生在堆内存中,当一个对象没有存在的必要的时候,占着内存明显不行,所以Java内置的GC会对没有必要存在的内存区域进行回收,那么,如何判断一个对象已经没有使用价值了,或者说,已死了呢?
首先,最直观的方式是在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就+1,当引用值失效时,再-1,任何时刻计数器值为0的对象就是不可能再被使用的,客观的说,这种方式实现简单,判定效率高,在大部分情况下是一个不错的算法,但是它最大的问题在于不能解决对象之间相互引用的问题,例如:objA.instance = objB; objB.instance = objA; 这样两个对象之间互相引用,引用计数器的值都不为0,但是很明显除此之外没有别的地方需要这两个对象,此时使用这种回收机制就显得无能为力。此时,另一种算法:可达性分析,在主流的商用程序语言中,都使用到了这种算法,这种算法的思路是:从一系列定义为GC-Root的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为“引用链”,当一个对象到GC-Root对象没有任何引用链相连时,即无法到达时,认为该对象已经没用了,这种算法很好的解决了上述中提到的对象之间互相引用的问题。
在Java中,可以作为GC-Roots的对象有以下几种:
虚拟机栈中引用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈JNI中引用的对象
从上文可知,无论是引用计数器和可达性分析(引用链)都与引用这个概念相关,那么什么是引用呢?在JDK1.2以前,引用的定义很直接:如果reference类型数据中存储的是另一块内存的起始地址,就称这块内存存在着一个引用。这种定义很纯粹,但是有些狭隘,它无法描述那些“食之无味,弃之可惜”的对象,我们希望能描述这样一类对象:当内存空间还足够时,可以保留在内存中,如果内存空间在垃圾回收后还是很紧张,则可以抛弃这些对象,很多系统的缓存功能都符合这样的应用场景。于是,在JDK1.2之后,Java定义了四种引用类型:
1.强引用:在代码中普遍存在,类似"Object a = new Object()"就是强引用,只要强引用存在,垃圾回收器就不会回收被引用的内存。
2.软引用:Soft Reference,用来描述一些有用但不是必须的对象,当将要发生内存溢出时,会将这些对象列为回收范围进行第二次回收,如果这次回收后还没有足够的可用内存,才会抛出内存溢出。
3.弱引用:描述的对象与软引用相似,但是比软引用更弱一些,只能生存到下次GC之前,当虚拟机进行内存回收时,无论是否存在软引用,都会对该对象进行回收,在JDK1.2之后,提供了WeakReference来表示弱引用。
4.虚引用:Phantom Reference,也被称为幽灵引用或幻影引用,是最弱的一种引用关系,他的存在不会对对象的生存时间构成任何影响,也无法通通过虚引用获取一个对象实例,引入它只是为了在被系统回收时得到一个通知。
tips:当一个对象被可达性算法和引用计数法都判定为“死亡”时,还会进行一次筛选,如果这个类覆盖了Object类的finalize()方法(对于一个对象,这个方法只会调用一次),且可以调用时,会先调用该方法,执行完该方法后如果还是没有满足可存活的条件,才会将其回收,这是文章作者特意提到的,对象可以在该方法中进行“自救”,例如:
将自己this赋值给一个引用,但是只能自救一次,因为该方法只会被调用一次。
但是作者建议不要使用这种方式拯救对象,因为调用不确定性大,开销大,用finalize()可以做到的,用try-finally可以做的更好,只须了解有这个方法存在即可。
方法区也是会发生内存回收的
很多人会认为方法区中不会进行内存回收的操作,虽然在方法区进行内存回收的效率比较低(正常在堆中进行一次GC大约可以释放70%~95%的内存空间),但是还是会执行内存回收,回收的对系那个有两种,一是废弃的常量,二是无用的类。
1.例如一个常量“abc”已经进入了常量池,但是当前系统没有一个String对象是指向该常量,如果这时候发生了内存回收,并且有必要的话,就会将该常量回收。
2.判断一个常量是否无用简单,但是判断一个类是否无用比较复杂,需要满足多个条件,首先,该类的所有实例均以被回收,也就是Java堆中不存在该类的实例;其次,该类的ClassLoader已经被回收;并且,该类的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。虚拟机可以对上述类进行回收,但是仅仅是可以,而不是像对象一样,不使用了就必然会回收。
下一章会介绍虚拟机主要使用的几种垃圾回收算法。
深入理解JVM(四) -- 垃圾内存回收的判定方法和内容的更多相关文章
- 图解JVM垃圾内存回收算法
图解JVM垃圾内存回收算法 这篇文章主要介绍了图解JVM垃圾内存回收算法,由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率,下面博主和大家来一起学习一下吧 前言 首先,我们要讲 ...
- 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)
欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我博客 也欢迎关注公 众 号[Ccww笔记],原创技术文章 ...
- JVM(四)内存回收(二)
在上一节中"JVM(三)内存回收(一)"我讲到了垃圾回收的几种算法,算是解决了之前提到的3个问题中的最后一个. 关于内存回收,还应该了解常用的内存回收器(GC Collector) ...
- 深入理解JVM一垃圾回收算法
我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. 一.stop the world 在介绍 ...
- JVM(四) 垃圾回收
1. 堆内存结构 Java堆从GC的角度可以细分为:新生代(Eden区.From Survivor区和To Survivor区)和老年代. 1.1 新生代 新生代是用来存放新生的对象.一般占据堆的1/ ...
- 深入理解JVM——关于垃圾回收
关于垃圾回收 仿佛来自上海居委会大妈的灵魂拷问:“你是什么垃圾?” 不 今天我们要说的是JVM的垃圾回收 假如我是一个“人”类的“对象”,也和人的生命一样必有一死,可是“我真的还想再活500年~~”, ...
- 深入理解JVM(五) -- 垃圾回收算法
上篇文章我们了解到哪些内存区域和哪些对象可以被回收,这篇文章我们就来了解一下具体的垃圾回收算法的思路,不讨论具体的实现. 一 最基础算法 标记-清除(Mark-Swap) 为什么说他是最基础的算法,因 ...
- 理解JVM之Java内存区域
Java虚拟机运行时数据区分为以下几个部分: 方法区.虚拟机栈.本地方法栈.堆.程序计数器.如下图所示: 一.程序计数器 程序计数器可看作当前线程所执行的字节码行号指示器,字节码解释器工作时就是通过改 ...
- 深入理解JVM - 1 - Java内存区域划分
作者:梦工厂链接:https://www.jianshu.com/p/7ebbe102c1ae来源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处. Java与C++之间有一堵 ...
随机推荐
- cnetos6.5安装Varnish
安装依赖包: tar -zxvf docutils-0.13.1.tar.gz python setup.py install unzip pcre2-10.23.zip ./configure -- ...
- hdu1002 A + B Problem II[大数加法]
目录 题目地址 题干 代码和解释 参考 题目地址 hdu1002 题干 代码和解释 由题意这是一个涉及到大数的加法问题.去看了一眼大数加法的方法感觉头很大,然后突然发现Java可以流氓解决大数问题,毅 ...
- ubuntu之路——day13 只用python的numpy在较为底层的阶段实现单隐含层神经网络
首先感谢这位博主整理的Andrew Ng的deeplearning.ai的相关作业:https://blog.csdn.net/u013733326/article/details/79827273 ...
- ERROR: source database "template1" is being accessed by other users
一开始,开发童鞋说他在测试环境没有创建数据库的权限.心想,不对呀,开发环境没有怎么做权限管控,明明给予授权了.上来一看: postgres=# CREATE DATABASE "abce&q ...
- (8)Flask微电影项目会员中心其他页面搭建
会员中心修改密码.评论.登录日志和收藏电影4个页面的内容. 一.修改密码页面: {% extends "home/home.html" %} {% block css %} < ...
- Sword 计算机内存对齐
内存对齐理论 a.数据的对齐(alignment) 指数据的地址和由硬件条件决定的内存块大小之间的关系.一个变量的地址是它大小的倍数的时候,这就叫做自然对齐(naturally aligned). 例 ...
- 转:laydate只显示时分,不显示秒
@转载地址 原文全文: 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_40 ...
- 通过自定义EasyNVR的Logo、标题、版权等相关信息构建属于自己的摄像机网页视频直播服务
随着互联网基础设施建设的发展,4G/5G/NB-IoT各种网络技术.物联网技术的大规模商用,视频随时随地可看.可控.可回溯的诉求越来越多,互联网思维.架构和技术引入进传统监控行业里,成为新形势下全终端 ...
- Python 安装 MySQL-python ImportError: No module named 'ConfigParser'
系统: CentOS-6.4-x86_64 Python : Python 3.4.5 和 Python 3.5.2 安装 MySQL-python ,结果出错: ImportError: No mo ...
- socket支持ipv6
转自:https://www.jianshu.com/p/9926b99a7fef 以前cocos2d-x的项目里都使用的是libwebsocket,如果想支持ipv6,只需要升级相应的库即可,现在有 ...