JVM运行时数据区-方法区

2022-09-08 13:57:19 浏览数 (1)

JVM运行时数据区-方法区

  • 方法区和Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、域信息、方法信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。很多人都更愿意把方法区称为“永久代”(Permanent Generation)。从jdk1.7已经开始准备“去永久代”的规划,jdk1.7的HotSpot中,已经把原本放在方法区中的静态变量、字符串常量池等移到堆内存中。
  • 方法区主要存放Class,堆主要存放实例化的对象。
  • 在JDK1.8中,永久代已经不存在,存储类型信息、域信息、方法信息、运行时常量池都已经从永久代搬迁到了元空间。但元空间并不在Java虚拟机之中,而是使用本地内存。所以在默认情况下,元空间的大小仅受到本地内存限制,不过可以通过以下参数来指定元空间大小:
    • -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize指定 默认值依赖于平台。windows下,-XX:MetaspaceSize是21M,-XX:MaxMetaspaceSize的值是-1,即没有限制。
  • 方法区同堆一样,也是线程共享的内存区域。
  • 方法区与堆一样随JVM虚拟机启动被创建,以处于物理上不连续的内存空间,只需逻辑上连续即可。
  • 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:java.lang.OutofMemoryError:PermGen space 或者java.lang.OutOfMemoryError:Metaspace
    • 加载大量的第三方的jar包
    • Tomcat部署的工程过多(30~50个)
    • 大量动态的生成反射类
  • 关闭JVM就会释放这个区域的内存。
  • 方法区的垃圾收集主要回收两部分内容:常量池中废弃的常量和不再使用的类型。
  • 当俩个线程需要加载一个类型时,只会有一个请求classloader,另一个等待。
  • 局部变量表的大小以及异常表在方法区中。

0 人点赞