jvm回收方法区

很多人认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾收集,而且在方法区进行垃圾收集的“性价比”一般比较低:在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%~95%的空间,而永久代的垃圾收集效率远低于此。

永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类。回收废弃常量与回收Java堆中的对象非常类似。以常量池中字面量的回收为例,假如一个字符串“abc”已经进入了常量池中,但是当前系统没有任何一个String对象是叫做“abc”的,换句话说是没有任何String对象引用常量池中的“abc”常量,也没有其他地方引用了这个字面量,如果在这时候发生内存回收,而且必要的话,这个“abc”常量就会被系统“请”出常量池。常量池中的其他类(接口)、方法、字段的符号引用也与此类似。

判定一个常量是否是“废弃常量”比较简单,而要判定一个类是否是“无用的类”的条件则相对苛刻许多。类需要同时满足下面3个条件才能算是“无用的类”:

该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。

加载该类的ClassLoader已经被回收。

该类对应的java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

虚拟机可以对满足上述3个条件的无用类进行回收,这里说的仅仅是“可以”,而不是和对象一样,不使用了就必然会回收。是否对类进行回收,HotSpot虚拟机提供了-Xnoclassgc参数进行控制,还可以使用-verbose:class及-XX:+TraceClassLoading、 -XX:+TraceClassUnLoading查看类的加载和卸载信息。

在大量使用反射、动态代理、CGLib等bytecode框架的场景,以及动态生成JSP和OSGi这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出。

时间: 2024-10-06 21:19:33

jvm回收方法区的相关文章

JVM【第十四回】:【回收方法区】

很多人认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾手机,而且在方法区进行垃圾收集的"性价比"一般比较低:在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%~90%的空间,而永久代的垃圾收集效率远低于此. 永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类.回收废弃常量与回收Java堆中的对象非常类似.以常量池中字面量的回收为例,假如一个字符串"abc"已经进入了常

jvm 方法区

方法区在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内部表现形式.如,多字节变量在类文件是以big-endian存储的,但在加载到方法区后,其存放形式由jvm根据不同的平台来具体定义. jvm在运行应用时要大量使用存储在方法区中的类型信息.在类型信息的表示上,设计者除了要尽可能提高应用的运行效率外,还要考虑空间问题.根据不同的需求,jvm的实现者可以在时

java虚拟机之回收方法区

在java虚拟机中并没有规范规定需要对方法区即是新生代进行垃圾回收, 主要是这些区域的回收性价比极低, 一般在新生代中一般垃圾回收中可以达到70%到95%. 其中永久代中的垃圾回收主要回收的是两个部分, 一个部分是废弃的常量,判断一个常量是否废弃, 主要看这个常量在其他地方是否引用了这个字面量. 否则如果此时发生垃圾回收,即会回收这部分常量. 另外一部分是无用的类,判断一个类是否无用,主要看三点, 第一点是这个类的所有实例都被回收了,即是java堆中不存在该类的任何实例, 第二点是加载该类的cl

JVM方法区内存回收

很多人认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾收集,而且在方法区进行垃圾收集的"性价比"一般比较低:在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%~95%的空间,而永久代的垃圾收集效率远低于此. 永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类. 先来说说方法区内常量池之中主要存放的两大类常量:字面量和符号引用.字面量比较接近Java语言层次的常量概念,如文本字符串.被声明

深入JVM读书笔记(一)——jvm数据区基础知识

最近得空,就把<深入理解Java虚拟机>重新看了一遍,特写下现在的读书笔记,总结知识点,记录现在的理解,便于以后的回顾.下面的内容也会按照这本书的章节来划分知识点! Let's go! 想要了解Java虚拟机,一定要先明白Java运行时划分为哪些数据区域,具体的可以参考下图,按照是否为线程私有可以划分为: 线程私有:虚拟机栈.本地方法栈.程序计数器 线程共有:方法区.堆   下面详细说一下各个数据区的作用: 1. 程序计数器(Program Counter Register) 程序计数器是一块

GC回收方法区

很多人认为方法区(或者hotSpot虚拟机中的永久代)是没有垃圾收集的,java虚拟机规范中确实说过不要求虚拟机在方法区实现垃圾收集,而且在方法区中进行垃圾收集的"性价比"一般比较低:在堆中,尤其是新生代中,常规应用进行一次垃圾收集一般可以回收70% ~ 95%的空间,而永久代的垃圾收集效率远低于此. 永久代的垃圾收集主要是回收两部分内容:废气常量和无用的类.回收废弃常量与回收java堆中的对象非常类似.以常量池中字面量的回收为例,假如一个字符串"abc"已经进入了

第三章:回收方法区

方法区的垃圾回收,即使永生代的垃圾收集:主要回收两部分内容,废弃的常量和无用类. 回收废弃的常量与Java堆中的对象非常类似,以常量池中字面量的回收为例:假如一个字符串"abc"已经进入了常量池中,但是当前系统没有任何一个String对象的是叫做abc的,换句话说就是没有任何STring对象引用常量池中abc常量,也没有任何其他地方引用这个字面量,如果这时发生内存回收,这个abc常量就会被系统清理出常量池. 判断一个类是否是无用类,需要满足如下规则: 该类所有的实例都已经被回收了,也就

JVM内存结构——运行时数据区

在Java虚拟机规范中将Java运行时数据划分为6种,分别为: PC寄存器(程序计数器) Java栈 堆 方法区 运行时常量池 本地方法栈 一.PC寄存器(程序计数器) PC寄存器(Program Counter Register)严格来说是一个数据结构,它用于保存当前正常执行的程序的内存地址. 线程私有. 每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器.PC寄存器里保存有当前正在执行的JVM指令的地址. 每个线程都需要一个独立的程序计数器,各条线程之间

《深入理解Java虚拟机:JVM高级属性与最佳实践》读书笔记(更新中)

第一章:走进Java 概述 Java技术体系 Java发展史 Java虚拟机发展史 1996年 JDK1.0,出现Sun Classic VM HotSpot VM, 它是 Sun JDK 和 OpenJDK 中所带的虚拟机,最初并不是Sun开发 Sun Mobile- Embedded VM/ Meta- Circular VM BEA JRockit/ IBM J9 VM JRockit曾号称世界上最快的java虚拟机,BEA公司发布.J9属于IBM主要扶持的虚拟机 Azul VM/ BEA