方法区
不同版本具体实现
- 标准层面:方法区(Method Area)
- 具体实现层面:
- ≤JDK1.6 永久代
- =JDK1.7 永久代仍然存在,但是已经开始提出:去永久代
- ≥JDK1.8元空间(Meta Space)
永久代概念辨析:
- 从堆空间角度来说
- 新生代:从标准和实现层面都确定属于堆
- 老年代:从标准和实现层面都确定属于堆
- 永久代
- 名义上属于堆
- 实现上不属于堆
- 从方法区角度来说
- 方法区的具体实现:JDK 版本 ≤ 1.7 时,使用永久代作为方法区。
- 方法区的具体实现:JDK 版本 ≥ 1.8 时,使用元空间作为方法区。
元空间是什么
本身含义:万物初始,一件事情的源头或基本组成部分。
举例:元素、元始天尊、每年1月称为元月、1月1日称为元旦、元认知、元无知、元知识
对比类和对象,类相当于是对象的元信息。
JVM(Java虚拟机)内存分为堆内存、方法区、虚拟机栈、本地方法栈和程序计数器。其中,方法区被JDK1.8之后的版本取代,而元空间(Metaspace)则被引入。
元空间是一块本地内存,它用于存放类的元数据,例如类名、访问修饰符、字段、方法、注解等信息。这些信息在程序运行期间保持不变,存储在元空间中可以提高程序的运行效率。
元空间由Java虚拟机主动管理,可以将其看作是一块特殊的堆内存。相比于方法区,元空间的内存可调,可以使用-Xmx设置内存上限,且可以在适当的情况下自动进行垃圾回收。
元空间一般设置多大
在JVM中,元空间一般设置较大的内存空间才能满足应用程序对于类元数据的要求。根据应用程序的需要和计算机的硬件资源,可以根据实际情况进行内存的设置。
在JDK1.8版本中,元空间在Windows上的默认大小为21MB,而在Linux上则为24MB。如果元空间的内存已经不足,JVM会自动进行内存扩容。
一般来说,为了避免内存耗尽的风险,建议将元空间内存设置在256MB到1GB之间。
元空间和直接内存
JVM中元空间和直接内存是两个不同的概念。直接内存(Direct Memory)是为了手动分配Native内存而引入的,它与元空间不同。元空间是为了存储类的元数据而产生的。
直接内存是通过在Java堆外分配内存来实现,不受JVM的垃圾回收管理。而元空间是在线程栈和程序计数器之外的一部分虚拟机内存中。
元空间内存大小
在JDK1.8之前,JVM中的方法区是有内存大小限制的,大小由-Xmx及-XX:MaxPermSize设置,通常默认为64MB。而在JDK1.8版本之后,元空间的内存大小和直接内存一样,并且是可以进行动态调整的,不再受到固定的限制。
需要注意的是,在JVM的默认配置下,元空间的内存大小只有21MB。如果存储的类元数据过多,需要增加元空间的内存大小。可以使用JVM命令行参数-XX:MetaspaceSize设置元空间的初始大小,使用-XX:MaxMetaspaceSize设置元空间的最大大小。
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=1024m
元空间大小设置
在JVM中,我们可以通过调整元空间内存大小来优化内存使用效率。下面是几个常用的内存大小设置参数:
- -XX:MetaspaceSize设置元空间的初始大小
- -XX:MaxMetaspaceSize设置元空间的最大大小
- -XX:MinMetaspaceFreeRatio设置最小空闲空间比率,缺省值为40%
- -XX:MaxMetaspaceFreeRatio设置最大空闲空间比率,缺省值为70%
需要注意的是,这些参数的设置需要根据具体应用程序的需求和运行情况进行调整,避免出现内存不足的情况。
元空间存放什么内容
- 类信息:类中定义的构造器、接口定义
- 静态变量(类变量)
- 常量
- 运行时常量池
- 类中方法的代码
JVM元空间主要存储类的元数据信息,包括Java类名、字段、方法、注解等信息。这些信息在程序运行期间保持不变,可以存储在元空间中。
需要注意的是,元空间存储的不是Java类本身,而是Java类的元数据。Java类本身存储在Java堆内存中,而这些元数据则被存储在元空间中。
由于元空间存储的是类的元数据信息,因此当加载类的时候,元空间会增加内存使用。当卸载类的时候,元空间会释放相应的内存。
元空间占用JVM内存吗
在JVM中,元空间是一块本地内存,不属于Java堆内存。因此,元空间不占用Java堆内存,也不会被JVM的垃圾回收管理。
需要注意的是,元空间的内存使用情况仍然对应用程序的内存使用情况产生影响。因此,当应用程序需要使用的类元数据过多时,需要增加元空间的内存大小,以避免出现内存不足的情况。
元空间什么时候会进行垃圾回收
在JVM中,元空间不属于Java堆内存,不受JVM的垃圾回收管理。如果元空间的内存不足,JVM会自动进行内存扩容。
需要注意的是,元空间对内存使用情况的监控需要由Java虚拟机主动管理,可能会影响程序的性能。因此,在合适的情况下,可以手动对元空间进行内存回收。
可以使用JVM命令行参数-XX:MetaspaceSize和-XX:MaxMetaspaceSize设置元空间的大小,并调整GC参数,以控制元空间内存的使用情况。
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200