方法区
方法区存储什么?
存储已被虚拟机加载的类型信息、常量、静态变量、即时编译期编译后的代码缓存等。
类型信息(类class、接口interface、枚举enum、注解annotation):
这个类型的完整有效名称(包名.类名)
这个类型直接父类的完整有效名(对于interface或是java.lang.Object,都没有父类)
这个类型的修饰符
这个类型直接接口的有序列表
域(Field)信息
域信息包括:域名称、域类型、域修饰符(public、private、protected、static、final、volatile、transient的某个子类)
方法信息
方法名称
方法的返回类型
方法参数的数量和类型
方法的修饰符
方法的字节码、操作数栈、局部变量表及大小
异常表
为什么需要常量池?
一个java源文件中的类、接口,编译后产生一个字节码文件。而java中的字节码需要数据支持,通常这种数据会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用。在动态链接的时候会用到运行时常量池。
什么是运行时常量池?
运行时常量池是方法区的一部分
常量池表示Class文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
运行时常量池,在加载类和接口到虚拟机后,就会创建对应的运行时常量池。
运行时常量池,相对于Class文件常量池的另一重要特征是:具备动态性。
Hotspot中方法区的变化?
jdk1.6及之前:有永久代,静态变量存放在永久代上。
jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池、静态变量移除,保存在堆中
jdk1.8及以后:无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍在堆中
永久代为什么要被元空间替换?
1.为永久代设置空间大小是很难确定的。
元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。
2.对永久代进行调优是很困哪的。
字符串常量池为什么要调整?
因为永久代(元空间)的回收效率很低,在Full gc(整堆回收)的时候才会触发。而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足。放到堆里,能及时回收内存。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix