JVM之GCRoots详解

JVM之GCRoots详解
目录
面试题引子
什么是垃圾
判断对象是否可以被回收之引用计数法
判断对象是否可以被回收之枚举根节点可达性分析
Java中可以作为GC Roots的对象
1. 面试题引子
一面:GC Roots如何确定?哪些对象可以作为GC Roots?
2. 什么是垃圾
1.简单说就是内存中已经不再被使用到的空间就是垃圾

3. 判断对象是否可以被回收之引用计数法
Java中,引用和对象是有关联的。如果要操作对象则必须用引用进行。
因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,给对象中添加一个引用计数器,每当有一个地方引用它,计数器值加1,每当有一个引用失效时,计数器值减1。

任何时刻计数器值为零的对象就是不可能再被使用的,那么这个对象就是可回收对象。

那为什么主流的Java虚拟机里面都没有选用这种算法呢?其中最主要的原因是它很难解决对象之间相互循环引用的问题。

4. 判断对象是否可以被回收之枚举根节点可达性分析
为了解决引用计数法的循环引用问题,Java使用了可达性分析的方法。
所谓"GCroots,或者说tracingGC的“根集合”就是一组必须活跃的引用。
基本思路就是通过一系列名为”GCRoots”的对象作为起始点,从这个被称为GC Roots的对象开始向下搜索,如果一个对象到GCRoots没有任何引用链相连时,则说明此对象不可用。也即给定一个集合的引用作为根出发,通过引用关系遍历对象图,能被遍历到的(可到达的)对象就被判定为存活,没有被遍历到的就自然被判定为死亡。

5. Java中可以作为GC Roots的对象
虚拟机(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(即一般说的native方法)中引用的对象
引用地址https://blog.csdn.net/weixin_41910694/article/details/90706652

原文地址:https://www.cnblogs.com/zhuyeshen/p/12579308.html

时间: 2024-10-09 21:21:28

JVM之GCRoots详解的相关文章

JVM类加载机制详解(二)类加载器与双亲委派模型

在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可以通过jar包.war包.网络中获取.JSP文件生成等方式. 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.这里只是转化了数据结构,并未合并数据.(方法区就是用来存放已被加载的类信息,常量,静态变量,编译后的代码的运行时内存区域) 3.在内存中生成一个代表这个类的java.lan

JVM运行原理详解

1.JVM简析: 作为一名Java使用者,掌握JVM的体系结构也是很有必要的. 说起Java,我们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java虚拟机和Java应用程序接口(Java API).它们的关系如下图所示: Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上.这个平台的结构如下图所示:     运行期环境代表着Java

JVM -verbose参数详解(转)

转自:http://www.javaranger.com/archives/367 java -verbose[:class|gc|jni] 在输出设备上显示虚拟机运行信息. 1.java -verbose:class 在程序运行的时候有多少类被加载!你可以用verbose:class来监视,在命令行输入java -verbose:class XXX  (XXX为程序名)你会在控制台看到加载的类的情况. verbose和verbose:class含义相同,输出虚拟机装入的类的信息,显示的信息格式

JVM类加载机制详解(一)JVM类加载过程

首先Throws(抛出)几个自己学习过程中一直疑惑的问题: 1.什么是类加载?什么时候进行类加载? 2.什么是类初始化?什么时候进行类初始化? 3.什么时候会为变量分配内存? 4.什么时候会为变量赋默认初值?什么时候会为变量赋程序设定的初值? 5.类加载器是什么? 6.如何编写一个自定义的类加载器? 首先,在代码编译后,就会生成JVM(Java虚拟机)能够识别的二进制字节流文件(*.class).而JVM把Class文件中的类描述数据从文件加载到内存,并对数据进行校验.转换解析.初始化,使这些数

JVM 类加载机制详解

原文出处: ziwenxie 如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的入口.注意这里不一定非得要从一个Class文件获取,这里既可以从ZIP包中读取(比如从jar包和war包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将JSP文件转换成对应的Class类). 验证

深入理解JVM之四:详解垃圾收集器

前言 前面已经对垃圾收集算法有了较为详细的介绍,这里我们将对JVM中具体的垃圾回收器进行介绍,在虚拟机规范中并没有对垃圾回收器如何实现具体介绍,因此每个厂商的垃圾回收器可能会完全不同,但是我们介绍的是基于JDK1.7之后的Hotspot虚拟机(包括前面对Java虚拟机的介绍也是基于jdk1.7版本的).在Hotspot中,虚拟机的收集器主要有下: 可以看到垃圾收集器是按对象的分代来划分的,可以用线条连接的垃圾回收器表示两者可以配合使用.可以看到新生代垃圾收集器有Serial.ParNew.Par

JVM内存配置详解(转)

前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的OOM了!问题虽然蹊跷,但也趁此机会再次对JVM堆模型.GC垃圾算法等进行了一次系统梳理: 基本概念 堆/Heap JVM管理的内存叫堆:在32Bit操作系统上有4G的限制,一般来说Windows下为2G,而Linux 下为3G:64Bit的就没有这个限制. JVM初始分配的内存由-Xms指定,默认是

JVM参数配置详解

1. JVM中的年轻代,年老代和持久代区别与联系 JVM中的GC算法采用的是分代收集的策略,即将内存分为几个区域,将不同生命周期的对象放在不同区域里.如下所示: (1)在GC收集的时候,频繁收集生命周期短的区域(年轻代): (2)比较少的收集生命周期比较长的区域(年老代): (3)基本不收集的永久区(持久代). 年轻代分为1个Eden区和2个Survivor区,新建对象都保存在Survivor区中.当Eden区满则进行Minor GC,将Eden区和一个Survivor区清理到年老代中.这时不能

JVM内存区域详解

1. 程序计数器 现在多线程越来越普遍了,但是对于单核处理器而言,同一个时刻只能够执行一行指令.多个线程的同时执行,实际上是通过线程切换来实现的.一种简单的方式就是,每个线程执行一段时间后,就切换到另外一个线程去执行.当线程A执行到某行字节码指令时被挂起,这个时候切换到线程B执行一段时间后,又需要切换回来执行线程A,那么需要从上一次中断的地方继续执行.所以需要每一个线程都有一个程序计数器,用来存储当前需要执行的字节码指令的地址. 2. 栈空间 每个线程都有一个执行方法,而方法的局部变量表.操作数