首页 新闻 搜索 专区 学院

JVM中运行时常量池的回收问题

0
悬赏园豆:100 [待解决问题]

我们知道JVM采用可达性分析来进行对象内存回收,但是作为GC Roots的四种对象本身是怎么回收的呢?虚拟机栈和本地方法栈引用的对象可以在栈回收(方法调用结束)之后回收,类静态属性引用对象可以在类回收之后被回收,但是常量引用对象该怎么回收呢?

《深入理解Java虚拟机》中并没有给出比较明确的说法,举了个例子,String对象“abc”,只要系统中没有String对象指向“abc”,就可以在必要的时候回收“abc”。那怎么判断系统中没有“abc”的引用呢?计数算法(如果是这样,那常量池中的引用就一定不会出现循环引用的问题吗)?还是通过别的什么方式呢?

Feng_zhulin的主页 Feng_zhulin | 菜鸟二级 | 园豆:329
提问于:2016-11-25 10:47
< >
分享
所有回答(4)
0

这个主要还是看不同的jvm的实现。计数法这个现在应该不怎么用了,都是判断有没有引用来的。

常量池应该是个类似很大的table,由于有table对其内部字符串的引用致使常亮不会被回收。但如果出现空间紧张的情况我觉得可能使用某些算法,比如lru确认那些不在被外部引用的字符串是不是可以销毁。

Daniel Cai | 园豆:10374 (专家六级) | 2016-11-25 15:55

“都是判断有没有引用来的“

怎么判断的呢?如果分不同的实现,那在主流jvm实现(hotspot)一般是怎么判断的呢?

支持(0) 反对(0) Feng_zhulin | 园豆:329 (菜鸟二级) | 2016-11-25 16:06

@Feng_zhulin:

三个步骤:

1. stop the world

2. 从gc roots开始mark所有可达对象

3. sweep 所有未标记对象

支持(0) 反对(0) Daniel Cai | 园豆:10374 (专家六级) | 2016-11-25 16:13

@Daniel Cai: 你还是没有弄明白我问的东西,可以通过GC Rootsmark可达对象,然而GC Roots本身谁来mark呢?它们本身在需要回收的时候要怎么办呢?我在问题中指出了四种GC Roots对象其中的三种该怎么回收,现在疑问的是第四种,方法区中的常量引用对象该如何GC。

支持(0) 反对(0) Feng_zhulin | 园豆:329 (菜鸟二级) | 2016-11-25 17:03
0

GC roots 是一组对象引用,或者说是指针,废弃常量也能通过这些根引用来识别。

创心coder | 园豆:736 (小虾三级) | 2017-03-17 11:12
0

您好,最近我也在思考这个问题,请问您现在有什么思路了吗?

编程迷思 | 园豆:202 (菜鸟二级) | 2020-02-19 08:02
0

你的理解应该有问题,你说的GC ROOTS四个对象,那个也是引用啊。比如栈引用的对象。你的栈退出后这个应用就没有了就不引用了啊,同样的方法区类卸载了常量和静态属性的引用就没有了。你可以理解那四个有一个Root的根。对应的场景消失了,他们也就不引用了,就可以销毁。只是从这个虚拟的Root开始是否可达

邀月入梦 | 园豆:215 (菜鸟二级) | 2020-03-31 20:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册