MST

星途 面试题库

面试题:Java中方法区和元空间的区别

请简要阐述Java 8之前方法区的概念,以及Java 8引入元空间后,方法区和元空间在内存管理、存储内容等方面存在哪些区别?
18.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

Java 8之前方法区的概念

  1. 定义:方法区是Java虚拟机规范中定义的一块内存区域,它属于堆内存的逻辑组成部分,但物理上可能不连续。
  2. 作用:用于存储已被虚拟机加载的类信息(如类的版本、字段、方法、接口等)、常量、静态变量以及编译器编译后的代码等数据。它是各个线程共享的内存区域。
  3. 实现:在HotSpot虚拟机中,方法区被习惯称为“永久代”,虽然Java虚拟机规范中并没有对如何实现方法区做出强制规定,但HotSpot虚拟机使用永久代来实现方法区,这使得Java应用更容易遇到内存溢出问题,因为永久代有固定大小限制,当加载的类过多等情况导致空间不足时就容易溢出。

方法区(永久代)和元空间的区别

  1. 内存管理
    • 方法区(永久代):有固定大小限制,当方法区中存储的数据量超过其大小限制时,容易抛出OutOfMemoryError: PermGen space异常。并且其内存回收主要针对常量池的回收和类型卸载,相对复杂且效果有限。
    • 元空间:使用本地内存(Native Memory),不再有永久代的固定大小限制,理论上只要系统本地内存足够,就不会因为类的不断加载而导致内存溢出。元空间的内存分配和回收由操作系统管理,在类卸载等场景下,元空间的内存回收相对更高效。
  2. 存储内容
    • 方法区(永久代):除了类的元数据信息(类信息、常量、静态变量等),字符串常量池也存储在永久代中。
    • 元空间:主要存储类的元数据信息,字符串常量池被移至堆内存中。元空间存储的类元数据信息与类加载器紧密相关,每个类加载器都有对应的一块元空间区域,类加载器回收时,其对应的元空间也会被回收。