8.方法区(线程共享)

一、栈、堆、方法区的交互关系

二、方法区的理解

	jdk7是永久代的一个实现,jdk8是元空间的一个实现
	和堆空间很类似,也是存储数据的地方,加载的类太多的话,容易报OOM:metaSpace

三、设置方法区的大小与OOM

3.1、调优

四、方法区的内部结构

4.1、方法区主要存什么?

类型信息、常量信息、静态变量、即时编译器编译后的代码缓存、类的加载器等
类型信息:
对于每个的类型(类、接口、枚举、注解),JVM必须在方法区存储一下信息:
         类(Class)信息:
1>这个类的完整有效名称
2>这个类的直接父类的完整有效名
3>这个类的修饰符
4>这个类的直接接口的一个有序列表
         域(Filed)信息:
名称、类型、修饰符
         方法(Method)信息:
名称、返回值类型、参数、修饰符、异常表

4.1.1、常量池表(Constant Pool Table)

	包括各种字面量和对类型、域、方法的符号引用(地址)。

4.1.2、为什么需要常量池呢?

	比如说,有一个方法, 多个对象调用此方法,没有必要声明很多方法,、
	只需要在常量池中声明一个 此方法,然后多个对象调用它的话,直接指向它就好了;
	(#XX  就是符号引用,指向真正的引用)

4.1.3、常量池中有什么?

4.2、小结:

常量池,可以看做一张表,虚拟机指令根据这张表找到要执行的类名、方法名、参数名、字面量等类型

4.3、运行时常量池

	符号引用和真实引用 : 就好比  我的名字  和  我本人
										我的名字就是符号引用
										我的真人就是真实引用
	运行时常量池方法区的一部分
    常量池表是字节码文件中的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容在类加载后存放在方法区的 运行时常量池 中

	此时,不再是常量池中的符号地址了,这里转为 真实地址

    相对于常量池的一个重要特征:动态性

五、方法区的举例使用

第一步

第二步

	先看程序计数器执行到哪了,然后压入 操作数栈

第三步

	然后执行下一步压入本地变量表

...

第N步

下一步

六、方法区的演变细节

6.1、JDK6.......方法区(永久代)在JVM中

6.2、JDK7.......方法区(永久代)在JVM中

6.3、JDK8.......方法区(元空间)不在在JVM中,在本地内存

永久代为什么要被元空间替代?

**1>永久代设置空间的大小 很难确定(空间小还容易产生full GC,大了还浪费)
如果动态加载类过多,容易产生OOM
元空间使用本地内存:元空间不在虚拟机中,因此,元空间的大小仅售本地内存的影响
2>对永久代的调优很困难。(full GC)
**

StringTable为什么要调整

七、方法区的垃圾收集

方法区的垃圾回收两部分内容:常量池中废弃的常量、不再使用的类型

变量的垃圾回收

类的垃圾回收

八、总结

九、大厂面试题

posted @ 2021-07-08 16:04  宋佳强  阅读(193)  评论(0)    收藏  举报