您的位置 首页 java

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

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

方法区概述

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

方法区、栈和堆的关系

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

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

之所以不同Jdk版本抛出的异常有区别,是因为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、不再使用的类型( class interface 等)。

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

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

文章来源:智云一二三科技

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

文章地址:https://www.zhihuclub.com/189445.shtml

关于作者: 智云科技

热门文章

网站地图