专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java面试必考问题:Java方法区存储了哪些数据

temp10 2024-12-11 17:11:42 java教程 11 ℃ 0 评论

前文《Java面试必考问题:JVM内存区域如何划分? 》介绍了Java虚拟机内存的划分,主要包括5个部分:方法区、堆、虚拟机栈、本地方法栈以及程序计数器,其中方法区和堆是各线程共享的存储区域,关于堆的内存管理机制在前面的文章《Java面试必考问题:Java堆内存管理机制 》中已经介绍过,本文重点介绍一下Java方法区。

方法区概述

我们还是以HotSpot VM来介绍方法区(Method Area)是如何实现的,内存又是如何管理的。对于HotSpot VM而言,方法区还有一个别名叫做Non-Heap(非堆),意思就是要和堆(Heap)分开。方法区可以看作是一块独立于Java堆的内存空间。

Java面试必考问题:Java方法区存储了哪些数据

创建一个新的对象,对象引用在虚拟机栈中,对象实例数据在堆中,实例数据中还包括对象类型数据的指针,对象类型数据则存放在方法区。

方法区的大小决定了系统可以保存多少个类,和堆一样,方法区也可能会抛出内存溢出错误。如果系统定义了太多的类,就有可能导致方法区溢出。在Jdk1.7版本及以前,会抛 java.lang.OutofMemoryError : PermGen space;在Jdk1.8及以后,会抛 java.lang.OutofMemoryError : Metaspace

之所以不同Jdk版本抛出的异常有区别,是因为HotSpot的变化。《Java界大名鼎鼎的HotSpot虚拟机的演进之路 》中曾介绍过在Jdk1.8版本中,HotSpot VM用元空间取代了之前的永久代来实现方法区。元空间的本质和永久代类似,都是对JVM规范中方法区的实现,两者的主要区别在于:元空间不在虚拟机设置的内存中,而是使用本地内存。

方法区的内存结构

方法区保存的信息包括:

(1)类型信息:包括了JVM加载类型(类class、接口interface、枚举enum、注解annotation)的完整有效名称(包名+类名)、其直接父类的完整有效名称、类型的修饰符、其直接继承的接口列表。

(2)域(成员变量)信息:类型的所有成员变量的相关信息以及成员变量的声明顺序。

(3)方法信息:包括了类型的成员方法的名称、返回类型、参数列表、修饰符、字节码、操作数栈、局部变量表、异常表等。

(4)静态变量:non-final的静态类变量和全局常量。区别在于全局常量在编译器给指定值,静态类变量在加载时准备阶段赋初值,初始化阶段再给指定值。

(5)JIT代码缓存:即时编译产生的代码缓存,将热点代码编译成与本地平台相关的机器码,并保存到内存。

(6)运行时常量池:各种字面量和对类型、域和方法的符号引用。

方法区的大小和GC

以Jdk1.8版本的HotSpot为例,元数据区的大小可以使用参数 -XX:MetaspaceSize-XX:MaxMetaspaceSize 指定。默认的 XX:MetaspaceSize 值为21MB,-XX:MaxMetaspaceSize 默认为-1,即没有限制。

XX:MetaspaceSize元空间初始大小,一旦触及这个水位线,会触发垃圾回收(GC)并卸载没用的类。如果元空间初始大小设置过低,那么会频繁触发GC,为避免如此,一般将 XX:MetaspaceSize 设置为相对较高的值。

-XX:MaxMetaspaceSize 元空间最大可分配大小,默认情况下,元空间最大的大小是系统内存的大小,元空间一直扩大,虚拟机可能会消耗完所有的可用系统内存。

方法区GC主要回收的内存包括:

1、常量池中没被引用的常量:字面量和符号引用。

2、不再使用的类型(classinterface等)。

对类型进行回收不是必要的,HotSpot虚拟机提供了-Xnoclassgc 参数进行控制,可以关闭虚拟机对 class 的垃圾回收功能。

我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,欢迎大家关注,谢谢。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表