主要针对Java堆和方法区

1、判断对象是否已“死”

Java堆中存放着几乎所有的对象实例,垃圾回收器在对堆进行回收之前,首先应该判断这些对象哪些还“存活”,哪些已经“死亡”。

(1)引用计数法

A. 工作流程

给每个对象附加一个计数器,每当有一个地方引用此对象。计数器+1;每当有一个地方不再引用此对象,计数器-1;在任意时刻,只要对象引用计数器值为0,任务此对象已经“死亡”。(没有“死亡”的对象一定不会被垃圾回收回收)

System.gc()”:强制进行垃圾回

B. 优缺点

优点:实现简单,判定效率较高,大多数情况下都是一个不错的算法(phthon、C++智能指针都采用引用计数器算法判断无用对象)

缺点:无法处理对象循环引用问题,所以Java不采用引用计数算法。

(2)可达性分析算法

A. 工作流程

通过一系列称之为“GC Roots”的对象作为起点,然后向下搜索,如果当前对象到GC Roots有路可走(GC Roots到当前对象可达),认为此对象还存活;如果当前对象到GC Roots没有引用链,认为此对象不可用。

B. 什么对象可作GC Roots

1)虚拟机栈中(局部变量表)引用的对象

2)本地方法栈中引用的对象

3)方法区中类静态变量引用的对象

4)方法区中常量引用的对象

(3)再谈引用

在jdk1.2对引用进行了扩充:

A. 强引用(Strong Reference)

强引用指的是程序代码中普遍存在的,类似于“Object obj = new Object()这类引用,只要当前对象至少有一个强引用存在,垃圾回收器就永远不会回收此对象实例,即便发生OutOfMemoryError异常也不会。

B. 软引用(Soft Reference)

软引用描述的是一些有用但不必须的对象,对于只被软引用引用的对象,在内存足够时,不会进行GC,在系统即将发生OutOfMemoryError异常之前,会将这些对象列入回收范围进行第二次GC,如果这次回收还没有足够空间,JVM会抛出OutOfMemoryError异常信息。

Jdk1.2之后,用SoftReference类来描述软引用。

C. 弱引用(Weak Reference)

弱引用描述的是非必须对象,但它的强度弱于软引用。仅仅被弱引用引用的对象,最多只能生存到下一次GC之前,当垃圾回收器开始工作时,不管当前内存是否够用,都会回收掉被弱引用引用的对象。

Jdk1.2之后,用WeakReference类来描述弱引用

D. 虚引用(Phantom Reference)

虚引用也被称为“幽灵引用”或“幻影引用”。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的目的:在这个对象被垃圾回收时会收到一个系统通知。

Jdk1.2之后,PhantomReference类来实现虚引用。

(4)判断一个对象真正的“死亡”

判断一个对象真正“死亡”需要经历两次标记。如果当前对象在进行可达性分析之后,发现它到GC Roots不可达,则会对其进行第一次标记并且进行一次筛选。帅选的依据有两点:

1)如果当前对象没有覆写finalize()方法或者它的finalize()方法已经被JVM调用过,则认为此对象真正“死亡”,下一次GC时将其回收。

2)如果当前对象通过帅选,那么对象会被放置在一个F-Queue的队列中,并在稍后有JVM的Fianlizer线程执行它的finalize()方法。

Finalize()方法时对象逃脱死亡经历的最后一次机会,垃圾回收器将对F-Queue队列进行第二次标记,如果对象在finalize()成功解救自己,则会被移出回收序列,否则,宣告死亡。

finalize()方法只会被JVM调用一次,不推荐使用,在jdk1.9之后,finalize()方法加上了@Deprecated(过期处理)注解。

(5)回收方法区

方法区的垃圾回收主要回收两部分内容:废弃常量、无用类

1)废弃常量:废弃常量的回收与Java堆对象回收类似。

2)无用类:

判断一个类为无用类条件有三个:

a. 该类的所有实例对象都已经被垃圾回收,即在Java堆中不存在任何该类实例。

b. 加载该类的ClassLoad也已经被回收。

c. 该类对应的Class对象没有在任何其他地方被引用,即无法通过反射访问该类的属性、方法。

JVM会对满足以上三点的无用类进行回收(类卸载),仅仅是“可能”。

大量使用反射,动态代理的场景下,JVM会不定期的对方法区进行回收来防止永久代溢出。

JVM——对象已“死”的判定的更多相关文章

  1. JVM学习记录-对象已死吗

    前言 先来回顾一下,在jvm运行时数据区,分为两部分,一个部分是线程共享区,主要包括堆和方法区,另一部是线程私有区分包括本地方法栈,虚拟机栈和程序计数器.在线程私有部分的三个区域是随着线程生和灭的.栈 ...

  2. JVM 判断对象已死,实践验证GC回收

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 提升自身价值有多重要? 经过了风风雨雨,看过了男男女女.时间经过的岁月就没有永恒不变 ...

  3. Java对象已死吗 深入理解Java虚拟机笔记

    1.引用计数器法 给每个对象设置一个计数器,每当有一个引用就给计数器的值+1,引用时小时就减一,当计数器值为0是就可以回收掉了. 主流虚拟机都没有使用这种算法,循环依赖问题 2.可达性分析: 思路是通 ...

  4. 《深入理解java虚拟机》笔记(4)对象已死吗

    一.垃圾回收器回收的对象 虚拟机内存区域中程序计数器.虚拟机栈.本地方法栈随线程而生,随线程而灭.这3个区域内存分配和回收都具备确定性.因此不需要过多考虑回收问题. 而Java堆和方法区不一样,这部分 ...

  5. JVM——垃圾回收资格的判定

    一:判断一个对象是否已死 1:引用数算法:给对象加个引用计数器,被引用时加一,引用失效减一,在任何时刻一直为0的就说明不会被使用,但是由于一种情况的存在,导致这种算法不被JVM所考虑,在两个对象相互引 ...

  6. MVC模式已死

    MVC模式:Model模型 View试图 Control控制器,是目前主流模式,被当作服务器软件入门基本模式学习和掌握,主流框架Struts 1/2 JSF Wicket基本都顺理成章支持MVC模式. ...

  7. JVM总结(一):概述--JVM对象探秘

    这一节我们来讨论一下JVM对象建立过程. JVM对象探秘 对象的建立 对象的内存布局 对象的访问定位 JVM对象探秘 对象的建立 对象的建立过程   图一:对象建立过程 1.类加载检查. 当JVM检测 ...

  8. NLP领域的ImageNet时代到来:词嵌入「已死」,语言模型当立

    http://3g.163.com/all/article/DM995J240511AQHO.html 选自the Gradient 作者:Sebastian Ruder 机器之心编译 计算机视觉领域 ...

  9. JVM对象存活判断方法

    一.GC主要针对什么区域 1. 程序计数器.虚拟机栈.本地方法栈,3个部分随线程而生死.每个栈桢分配多少内存基本上是在类结构确定下来时就已确定,大体上可认为是 编译期可知. 2. 而 堆 和 方法区 ...

随机推荐

  1. sed 替换命令使用

    输入文件不会被修改,sed 只在模式空间中执行替换命令,然后输出模式空间的内容.文本文件 employee.txt 101,John Doe,CEO 102,Jason Smith,IT Manage ...

  2. ssl 原理和建立连接过程

    ssl ("Secure Sockets Layer")加密原理 和https的关系https = http + ssl ssl 位置: SSL握手 证书主要作用是在SSL握手中, ...

  3. Linux使用ssh测试端口

    在windows上可以使用telnet客户端测试,在linux如果不方便安装telnet客户端的时候可以通关ssh来测试端口 具体命令如下 ssh -v -p 8080 root@59.207.252 ...

  4. docker中镜像的作用

    镜像原理镜像 镜像到底是什么?镜像是一种轻量级.可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码.运行时.库.环境变量和配置文件.1.Uni ...

  5. vue禁用浏览器回退

    解决方案 mounted() { history.pushState(null, null, document.URL) window.addEventListener('popstate', () ...

  6. css 按钮悬停效霓虹灯特效

    css 按钮悬停效霓虹灯特效 <!DOCTYPE html> <html lang="en"> <head> <meta charset=

  7. ITextRenderers html生成pdf 分页+横向

    1.pdf横向生成问题:格式化html是加上 @page{size:297mm 210mm;} public static String formatPdfHtml(String html,Strin ...

  8. [hdu6145]Arithmetic of Bomb II

    对于题中的"normal expression"(仅含加减乘和无前导0的非负整数,无括号)的计算,实际上并不需要通常的表达式求值,而可以用下述方式计算-- 维护三元组$(a,b,c ...

  9. [noi34]palindrome

    分割实际上就是不断地从两端取出一样的一段,并对剩下的串进行分割.下面我们来证明一下每一次贪心取出最短一段的正确性: 考虑两种分割方式,分别表示成S=A+B+A和S=C+D+C,其中A就是最短的一段,那 ...

  10. 【JavaSE】Java基础·疑难点汇集

    Java基础·疑难点 2019-08-03  19:51:39  by冲冲 1. 部分Java关键字 instanceof:用来测试一个对象是否是指定类型的实例. native:用来声明一个方法是由与 ...