方法区
一、堆、栈、方法区的交互关系
1.1 从线程共享角度
1.2
二、方法区的理解
2.1方法区的基本理解
- 方法区是独立于堆的内存空间
- 方法区(Method Area)与java堆一样,是各个线程共享的内存区域
- 方法区在jvm启动的时候被创建,并且它的实际的物理内存空间中和java堆区一样都可以是不连续的
- 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:java.lang.OutOfMemoryError:PermGen space或者java.lang.OutOfMemoryError:Metaspace
- 加载大量的第三方的jar包;Tomcat部署的工程过多(30-50个);大量动态的生成反射类;
- 关闭jvm就会释放这个区域的内存
三、设置方法区大小与OOM
3.1 设置方法区大小
3.2 如何解决OOM
四、 方法区的内部结构
4.1方法区存储什么?
方法区用于存储:
已被虚拟机加载的类型信息、常量、静态变量、即时编译器后的代码缓存等
4.2 类型信息
4.3 域信息
4.4 方法信息
4.5 运行时常量池
五、方法区使用举例
六、 方法区的演进细节
6.1 永久代的演进历程
6.2 永久代为什么要被元空间替代
6.3 StringTable为什么要调整
jdk7中将StringTable放到了堆空间。因为永久代的回收效率很低,在full GC的时候才会触发。而full GC是老年代的空间不足、永久代不足时才会触发。这就导致StringTable回收效率不高。而我们开发中会有大量字符串被创建,回收效率低,导致永久代内存不足。放到堆里,能及时回收内存
七、 方法区的垃圾回收
方法区的垃圾收集主要回收两部分内容:
1.常量池中废弃的常量;
2.不再使用的类;
7.1 常量的回收
7.2 类的回收
八、 总结
常见面试题