主要针对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. vue 插槽slot总结 slot看这篇就够了

    一直模糊所以梳理一下,看了好多篇园友的文章和官网文档在这整理一下 默认插槽 //slot组件<template> <div class="slots"> s ...

  2. 【代码更新】单细胞分析实录(21): 非负矩阵分解(NMF)的R代码实现,只需两步,啥图都有

    1. 起因 之前的代码(单细胞分析实录(17): 非负矩阵分解(NMF)代码演示)没有涉及到python语法,只有4个python命令行,就跟Linux下面的ls grep一样的.然鹅,有几个小伙伴不 ...

  3. docker使用redis过程出现的问题记录

    第一次使用docker搭建成功了单机版redis,但在使用过程中,还是遇到了不少问题,故而先把这些问题记录下来,以防后面再出现会忘记. 目前,只是在docker中搭建了三个单机版的容器,打算先捣鼓一周 ...

  4. Vue 基础自查——条件渲染和列表渲染

    v-if和v-show的区别是什么? v-if和v-for为什么不能一起用? v-for中的key有什么作用? 1 v-if 和 v-show 1.1 作用 都用来控制元素的显示和隐藏 1.2 控制元 ...

  5. GitHub上 README 增加图片标签

    hey Guys~ 你可能遇到的GitHub上好的项目都有一个非常棒的README,其中不乏用到一些非常好看的标签.比如下面这样: walle fastjson 那我们怎样自己添加一个高大上图片标签呢 ...

  6. kubernetes创建用户

    创建k8s User Account 使用openssl方法创建普通用户 准备工作 1 2 3 4 mkdir /root/pki/ 将k8s ca.pem  ca-key.pem 证书拷贝到此目录 ...

  7. 攻防世界 Misc 新手练习区 如来十三掌 Writeup

    攻防世界 Misc 新手练习区 如来十三掌 Writeup 题目介绍 题目考点 佛曰加密.base64.Rot13等加密方法的了解 Writeup 下载并打开附件 联想到佛曰加密,复制内容到 佛曰加密 ...

  8. Linux wget 命令 使用总结

    简介 wget命令用来从指定的URL下载文件.wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕.如果是服务器 ...

  9. MySQL之DDL数据定义语言:库、表的管理

    库的管理 常用命令 #创建库 create database if not exists 库名 [ character set 字符集名]; create database if not exists ...

  10. CommonJS与ES6 Module的使用与区别

    CommonJS与ES6 Module的使用与区别 1. CommonJS 1.1 导出 1.2 导入 2. ES6 Module 2.1 导出 2.2 导入 3. CommonJS 与 ES6 Mo ...