JVM如何判断哪些对象可以被回收
答案:2 悬赏:70 手机版
解决时间 2021-03-24 00:30
- 提问者网友:夢醒日落
- 2021-03-23 12:16
JVM如何判断哪些对象可以被回收
最佳答案
- 五星知识达人网友:鱼忧
- 2021-03-23 12:46
jvm要做垃圾回收时,首先要判断一个对象是否还有可能被使用。那么如何判断一个对象是否还有可能被用到?
如果我们的程序无法再引用到该对象,那么这个对象就肯定可以被回收,这个状态称为不可达。当对象不可达,该对象就可以作为回收对象被垃圾回收器回收。
那么这个可达还是不可达如何判断呢?
答案就是GC roots ,也就是根对象,如果从一个对象没有到达根对象的路径,或者说从根对象开始无法引用到该对象,该对象就是不可达的。
以下三类对象在jvm中作为GC roots,来判断一个对象是否可以被回收
(通常来说我们只要知道虚拟机栈和静态引用就够了)
虚拟机栈(JVM stack)中引用的对象(准确的说是虚拟机栈中的栈帧(frames))
我们知道,每个方法执行的时候,jvm都会创建一个相应的栈帧(栈帧中包括操作数栈、局部变量表、运行时常量池的引用),栈帧中包含这在方法内部使用的所有对象的引用(当然还有其他的基本类型数据),当方法执行完后,该栈帧会从虚拟机栈中弹出,这样一来,临时创建的对象的引用也就不存在了,或者说没有任何gc roots指向这些临时对象,这些对象在下一次GC时便会被回收掉
方法区中类静态属性引用的对象
静态属性是该类型(class)的属性,不单独属于任何实例,因此该属性自然会作为gc roots。只要这个class存在,该引用指向的对象也会一直存在。class 也是会被回收的,在面后说明
本地方法栈(Native Stack)引用的对象
一个class要被回收准确的说应该是卸载,必须同时满足以下三个条件
堆中不存在该类的任何实例
加载该类的classloader已经被回收
该类的java.lang.Class对象没有在任何地方被引用,也就是说无法通过反射再带访问该类的信息
这篇内容太少了,在说几句java中的四种引用类型
其实这四类引用的区别就在于GC时是否回收该对象
强引用(Strong) 就是我们平时使用的方式 A a = new A();强引用的对象是不会被回收的
软引用(Soft) 在jvm要内存溢出(OOM)时,会回收软引用的对象,释放更多内存
弱引用(Weak) 在下次GC时,弱引用的对象是一定会被回收的
虚引用(Phantom) 对对象的存在时间没有任何影响,也无法引用对象实力,唯一的作用就是在该对象被回收时收到一个系统通知
如果我们的程序无法再引用到该对象,那么这个对象就肯定可以被回收,这个状态称为不可达。当对象不可达,该对象就可以作为回收对象被垃圾回收器回收。
那么这个可达还是不可达如何判断呢?
答案就是GC roots ,也就是根对象,如果从一个对象没有到达根对象的路径,或者说从根对象开始无法引用到该对象,该对象就是不可达的。
以下三类对象在jvm中作为GC roots,来判断一个对象是否可以被回收
(通常来说我们只要知道虚拟机栈和静态引用就够了)
虚拟机栈(JVM stack)中引用的对象(准确的说是虚拟机栈中的栈帧(frames))
我们知道,每个方法执行的时候,jvm都会创建一个相应的栈帧(栈帧中包括操作数栈、局部变量表、运行时常量池的引用),栈帧中包含这在方法内部使用的所有对象的引用(当然还有其他的基本类型数据),当方法执行完后,该栈帧会从虚拟机栈中弹出,这样一来,临时创建的对象的引用也就不存在了,或者说没有任何gc roots指向这些临时对象,这些对象在下一次GC时便会被回收掉
方法区中类静态属性引用的对象
静态属性是该类型(class)的属性,不单独属于任何实例,因此该属性自然会作为gc roots。只要这个class存在,该引用指向的对象也会一直存在。class 也是会被回收的,在面后说明
本地方法栈(Native Stack)引用的对象
一个class要被回收准确的说应该是卸载,必须同时满足以下三个条件
堆中不存在该类的任何实例
加载该类的classloader已经被回收
该类的java.lang.Class对象没有在任何地方被引用,也就是说无法通过反射再带访问该类的信息
这篇内容太少了,在说几句java中的四种引用类型
其实这四类引用的区别就在于GC时是否回收该对象
强引用(Strong) 就是我们平时使用的方式 A a = new A();强引用的对象是不会被回收的
软引用(Soft) 在jvm要内存溢出(OOM)时,会回收软引用的对象,释放更多内存
弱引用(Weak) 在下次GC时,弱引用的对象是一定会被回收的
虚引用(Phantom) 对对象的存在时间没有任何影响,也无法引用对象实力,唯一的作用就是在该对象被回收时收到一个系统通知
全部回答
- 1楼网友:千杯敬自由
- 2021-03-23 14:20
比较常被提到的两种垃圾对象判定算法:
1.引用计数(Reference Counting)
概述:给对象添加一个引用计数器,每有一个地方引用这个对象,计数器值加1,每有一个引用失效则减1。
应用实例:Python中使用了这种算法判定死对象。
优点:实现简单、判定效率高
缺点:难以解决对象之间的循环引用问题
2.可达性分析(Reachability Analysis)
概述:从GC Roots(每种具体实现对GC Roots有不同的定义)作为起点,向下搜索它们引用的对象,可以生成一棵引用树,树的节点视为可达对象,反之视为不可达。
应用实例:Java,C#,Lisp都使用这种算法
=====================================================================
JVM使用“可达性分析算法”来判定一个对象是否会可以被回收,有两个细节需要注意:
Java中GC Roots包括以下几种对象:
a.虚拟机栈(帧栈中的本地变量表)中引用的对象
b.方法区中静态属性引用的对象
c.方法区中常量引用的对象
d.本地方法栈中JNI引用的对象
2.不可达对象一定会被回收吗不是。
执行垃圾回收前JVM会执行不可达对象的finalize方法,如果执行完毕之后该对象变为可达,则不会被回收它。
但一个对象的finalize方法只会被执行一次。
1.引用计数(Reference Counting)
概述:给对象添加一个引用计数器,每有一个地方引用这个对象,计数器值加1,每有一个引用失效则减1。
应用实例:Python中使用了这种算法判定死对象。
优点:实现简单、判定效率高
缺点:难以解决对象之间的循环引用问题
2.可达性分析(Reachability Analysis)
概述:从GC Roots(每种具体实现对GC Roots有不同的定义)作为起点,向下搜索它们引用的对象,可以生成一棵引用树,树的节点视为可达对象,反之视为不可达。
应用实例:Java,C#,Lisp都使用这种算法
=====================================================================
JVM使用“可达性分析算法”来判定一个对象是否会可以被回收,有两个细节需要注意:
Java中GC Roots包括以下几种对象:
a.虚拟机栈(帧栈中的本地变量表)中引用的对象
b.方法区中静态属性引用的对象
c.方法区中常量引用的对象
d.本地方法栈中JNI引用的对象
2.不可达对象一定会被回收吗不是。
执行垃圾回收前JVM会执行不可达对象的finalize方法,如果执行完毕之后该对象变为可达,则不会被回收它。
但一个对象的finalize方法只会被执行一次。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯
正方形一边上任一点到这个正方形两条对角线的 |
阴历怎么看 ? |