九、运行时内存篇——方法区
1、堆、栈、方法区的关系
2、方法区在哪里
《Java虚拟机规范》中明确说明: “尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。” 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap(非堆),目的就是要和堆分开。所以,方法区看作是一块独立于Java堆的内存空间。
3、方法区的理解
1、方法区(Method Area)与Java堆一样,是各个线程共享的内存区域。
2、方法区在JVM启动的时候被创建,并且它的实际的物理内存空间中和Java堆区一样都可以是连续的。
3、方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展。
4、方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:java.lang.OutofMemoryError:PermGen space 或者 java.lang.OutOfMemoryError: Metaspace。(加载大量的第三方的jar包;Tomcat部署的工程过多(30-59个);大量动态的生成反射类)
5、关闭JVM就会释放这个区域的内存。
4、HotSpot方法区的演进
在jdk1.7及之前,习惯上把方法区称为永久代。jdk1.8开始,使用元空间代替了永久代。
5、方法区的常用参数
方法区的大小不必是固定的,JVM可以根据应用的需要动态调整。
jdk7及以前:
-XX:PermSize来设置永久代初始分配空间。默认值是20.75M
-XX:MaxPermSize来设定永久代最大可分配空间。32位机器默认是64M,64位机器模式是82M
当JVM加载的类信息容量超过了这个值,会报异常OutofMemoryError:PermGenspace
jdk8及以后:
元数据区大小可以使用参数-XX:MetaspaceSize和-Xx:MaxMetaspaceSize指定,替代上述原有的两个参数。
默认值依赖于平台。windows下,-XX:MGtaspaceSize是21M,-XX:MaxMetaspaceSize的值是-1,即没有限制。
与永久代不同,如果不指定大小,默认情况下,虚拟机会耗尽所有的可用系统内存。如果元数据区发生溢出,虚拟机一样会抛出异常OutOfMemoryError:Metaspace
6、方法区存些什么
类型信息
域(Field)信息
方法信息
non-final的类变量
运行时常量池:常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型。
7、永久代和元空间
为什么要用元空间代替永久代?
- 对永久代设置空间大小是很难确定的。在某些场景下,如果动态加载类过多,容易产生Perm的OOM。比如某个实际web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类经常出现java.lang.OuOfMemoryError: PermGen space,而元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。
- 对永久代进行调优是很困难的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)