首页 > 试题广场 >

JVM的永久代中会发生垃圾回收么?

[问答题]
JVM的永久代中会发生垃圾回收么?
垃圾回收不会出现在永久代,但是如果永久代满了会触发完全垃圾回收。Hotspot的永久代是在方法区,主要存储的是类加载信息,静态变量以及常量,方法(字节码)等等,可以进行常量池回收和类型卸载。如果这个常量在其它任何对象都没被引用,则可以被回收。而类型卸载有点复杂,有以下三点要求:1.该类型的所有实例都已经被回收 2.该类型的ClassLoader已经被回收 3.该类型的java.lang.Class没有在任何地方被引用,该类型不能在任何地方以反射的方式实例化一个对象。在java8中,已经取消了永久代,但是引入了一个元数据区的navite内存区
编辑于 2018-05-23 08:19:13 回复(0)
更多回答
hotspot的方法区存放在永久代中,因此方法区被人们称为永久代。永久代的垃圾回收主要包括类型的卸载和废弃常量池的回收。当没有对象引用一个常量的时候,该常量即可以被回收。而类型的卸载更加复杂。必须满足一下三点,该类型的所有实例都被回收了,该类型的ClassLoader被回收了,该类型对应的java.lang.Class没有在任何地方被引用,在任何地方都无法通过反射来实例化一个对象
编辑于 2016-10-19 09:17:47 回复(1)
我想问下你们把答案复制一遍干嘛
发表于 2016-06-18 15:42:37 回复(14)
“相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入了方法区就如永久代的名字一样“永久”存在了。这区域的内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说,这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是必要的。”

Excerpt From: 周志明. “深入理解Java虚拟机:JVM高级特性与最佳实践(第2版).” iBooks. 
发表于 2017-09-21 14:16:19 回复(1)
永久代会垃圾回收,但是没有自己的垃圾收集器,是和老年代一起回收的
The Perm Gen panel plots the utilization of the Permanent Generation over time. The Permanent Generation is comprised of a single space, but does not have its own collector. Instead, this space is collected as part of the Old Generation. The height of the panel is fixed and, by default, the data is scaled according to the current capacity of the space. Since the current capacity of the space can change dynamically depending on the collector policy, visual artifacts may occur as the space shrinks and grows over time.
发表于 2019-03-25 11:11:48 回复(0)
JAVA堆内存分为持久代,年轻代和老年代。
年轻代存放新生成的对象。垃圾回收主要是针对这个区域。
在年轻代中经历了N次垃圾回收依然存活的对象被放入老年代中。
持久代存放的是类定义信息,与垃圾收集器关系不大。
发表于 2016-08-12 14:09:11 回复(4)
永生代也是可以回收的,条件是 1.该类的实例都被回收。 2.加载该类的classLoader已经被回收 3.该类不能通过反射访问到其方法,而且该类的java.lang.class没有被引用 当满足这3个条件时,是可以回收,但回不回收还得看jvm。
发表于 2019-06-21 12:38:52 回复(0)

不可以???这个答案错的吧,满足3个条件就能回收啊

发表于 2018-08-29 20:36:45 回复(0)
zll头像 zll
垃圾回收不会发生在永久代,如果永久代满了或超出了临界值,会触发jvm的完全垃圾回收(full gc)对其进行回收,正确的永久代大小会避免调用full gc
发表于 2016-03-19 21:05:21 回复(1)
永久带是方法区的一种实现,其中存储类模板信息,常量以及静态变量,其中不会发生垃圾回收,因此对于其空间的分配很重要,求大神解析我的理解对么!!
发表于 2017-10-01 17:16:37 回复(1)

垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。请参考下Java8:从永久代到元数据区
(注:Java8中已经移除了永久代,新加了一个叫做元数据区的native内存区)

发表于 2017-05-30 10:08:14 回复(0)
垃圾回收不会发生在永久代,如果永久代满了或超出了临界值,会触发jvm的完全垃圾回收
发表于 2017-03-27 16:09:12 回复(0)
请看JVM内存回收策略-方法区的垃圾回收部分

编辑于 2019-10-21 21:27:40 回复(4)
一群**,误导人。永生代也是可以回收的,条件是 1.该类的实例都被回收。 2.加载该类的classLoader已经被回收 3.该类不能通过反射访问到其方法,而且该类的java.lang.class没有被引用 当满足这3个条件时,是可以回收,但回不回收还得看jvm。
发表于 2018-07-30 00:03:36 回复(4)
垃圾回收不会发生在永久代,如果永久代满了活着超过了临界值,会出发完全垃圾回收(full gc)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小堆避免full gc是非常重要的原因。
发表于 2016-07-31 23:03:24 回复(0)
垃圾回收不会发生在永久代,如果永久代满了活着超过了临界值,会出发完全垃圾回收(full gc)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小堆避免full gc是非常重要的原因。请参考下java8:从永久代到原数据区(注:java8中已经移除了永久代,新加了一个叫做元数据区的native内存区)
发表于 2016-03-25 22:17:21 回复(0)
yyy头像 yyy
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。请参考下Java8:从永久代到元数据区
(注:Java8中已经移除了永久代,新加了一个叫做元数据区的native内存区)
发表于 2015-10-29 12:10:42 回复(0)

1.方法区的演进

  首先明确:只有HotSpot才有永久代。 其它虚拟机如JRockit、IBM J9等,是不存在永久代的概念的。
  HotSpot中方法区的变化:
  • jdk1.6及之前:有永久代,静态变量存放在永久代上。
  • jdk1.7:有永久代,但已经逐步“去永久代”。字符串常量池、静态变量从永久代移除,将其保存在堆中。(类静态变量与类Class对象捆绑在一起了)
  • jdk1.8及之后:无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍在堆。
(特别注意:JDK7之后的静态变量和字符串常量池StringTable都是存在堆中,而不是方法区)

  永久代为何会被元空间替换?
  • 第一:Oracle为了后续合并JRockit和Hotspot两款虚拟机。
  • 第二:永久代使用的是一开始就设定好的虚拟机内存,无法动态扩展内存空间,当一个工程加载太多类时,容易出现OOM。而元空间使用的是本地内存,在默认情况下,元空间的大小仅受限于本地内存限制。
  • 第三:对永久代调优是很困难的。

  字符串常量池(StringTable)为什么要做调整(方法区->堆)
  jdk7中将StringTable放到了堆空间中。因为永久代的回收效率很低,在Full GC的时候才会触发,而Full GC是在老年代或者永久代空间不足时才会触发。这就导致了StringTable回收效率不高。在实际开发中会有大量的字符串被创建,如果回收效率低,就无法及时释放可用内存,而如果放到堆里,就能及时回收内存。

2.方法区的垃圾回收

有人认为方法区不存在垃圾回收,其实在JVM规范中对方法区的约束也是非常宽松的,甚至提过可以不要求虚拟机在方法区实现垃圾回收。对于方法区的垃圾回收主要回收两部分:运行时常量池废弃的常量、不再使用的类型。
HotSpot虚拟机对常量池的回收策略是很明确的,只要常量池中的常量没有被任何地方引用,就可以被回收。
判断一个类型是否该被回收的条件就比较苛刻了,包括如下:
该类所有实例都已经被回收
加载该类的类加载器已经被回收;(这个条件除非是经过精心设计的可替换类加载器的场景,否则通常很难达成)
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法


大量使用反射、动态代理、CGLib等字节码框架,动态生成jsp以及频繁自定义类加载器的场景中,通常就需要JVM具备类型卸载能力(即在方法区实现回收),以保证不会对方法区造成过大的内存压力。
发表于 2021-12-23 22:26:19 回复(0)
会,当数据填满区域时
发表于 2020-09-20 16:47:10 回复(0)
会,如果永久代满了或者是超过了临界值,会触发完全垃圾回收。但这是在JDK1.8以前是这样,在JDK1.8以后永久代就被元空间所替代。
发表于 2020-07-07 15:52:16 回复(0)