方法区
方法区位置
在jdk1.8以前,方法区的位置在堆内存中的一部分叫做永久代,1.8后将堆中方法区移除改用本地内存中的元空间
jdk1.6
方法区在堆中,内部结构有运行时常量池,类信息,类加载信息
jdk1.8之后
此时方法区已经不占用jvm内存而是直接占用本地内存,此时运行时常量池的位置移动到了堆中
元空间溢出
由于元空间是存放在本地内存中大小几乎可以看做是物理内存的大小,所以想要看到元空间溢出需要通过idea在编译设置设置元空间大小
-XX:MaxMetaspaceSize=8m
在vm区域粘贴
如果元空间内存溢出的话报错为:
永久代溢出
设置永久代大小
-XX:MaxPermSize=8m
jdk1.6中永久代溢出报错为:
查看常量池
.java文件通过第一次编译为字节码文件后,其中包含了类基本信息,常量池,类方法自定义,虚拟机指令
进入到class文件目录下并通过javap -v查看字节码反编译后的语句
可以看到字节码中有关于main方法里面的执行指令和关于引用的常量池中指令的地址
我们找到#2对应的常量池地址,发现其类型为Fieldref,说明其引用了其他的变量,后面的地址说明引用了#21,#22的地址(在常量池中应该是直接拼接出结果)
在#21,#22又引用了#28,#29,#30的地址,类型为UTF8说明已经是最底层不需要再向下调用
运行时常量池
常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址