接上篇一款ava非常全面细致的Jvm学习内容
2021-05-12 14:10:19 9 举报
jvm的内存结构
作者其他创作
大纲/内容
四、方法区的内部结构
● 运行时常量池(Runtime Constant Pool)是方法区的一 部分。● 常量池表( Constant Pool Table) 是Class文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。,● 运行时常量池,在加载类和接口到虚拟机后,就会创建对应的运行时常量池。● JVM为每个已加载的类型(类或接口)都维护一个常量池。池中的数据项像数组项一样,是通过索引访问的。● 运行时常量池中包含多种不同的常量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了,这里换为真实地址。 ➢运行时常量池,相对于Class文件常量池的另--重要特征是:具备动态性。● 运行时常量池类似于传统编程语言中的符号表(symbol table),但是它所包含的数据却比符号表要更加丰富一一些。● 当创建类或接口的运行时常量池时,如果构造运行时常量池所需的内存空间超过了方法区所能提供的最大值,则JVM会 抛OutOfMemoryError异常。
运行时常量池
JVM的详细结构图
PC Registers
Thread1
线程私有
Thread2
虚拟机栈
Profler
Heap Area
程序计数器
三、设置方法区大小与OOM
本地方法库
运行时数据区(Runtime Data Area)
方法区
Interpreter
程序计数器PC Register forThread 1
Code Optimizer
Loading
ThreadLocal
堆
一、栈、堆、方法区的交互关系
Resolve
方法区,内部包含了运行时常量池。●字节码文件,内部包含了常量池。要弄清楚方法区,需要理解清楚ClassFile,因为加载类的信息都在方法区。要弄清楚方法区的运行时常量池,需要理解清楚ClassFile中的常量池。官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息外,还包含-项信息那就是常量池表(ConstantPoolTable),包括各种字面量和对类型、域和方法的符号引用。
JIT Compiler
为什么需要常量池?
类加载子系统Class Loader
本地方法栈
StackOverflowError
元空间
PC Register forThread 1
Initialization
运行时数居区结构图
OutOfMemoryError: Metaspace
Stack Area
Native MethodLibrary
LV OS DL RA
OutOfMemoryError: Java heap space
堆方法篇
GarbageCollection
Stack Frame
第四页
.........
堆区
执行引擎Execution Engine
一个java源文件中的类、接口,编译后产生-一个字节码文件。而Java中的字节码需要数据支持,通常这种数据会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用。在动态链接的时候会用到运行时常量池,之前有介绍。比如:如下的代码:public class SimpleClass{ public void sayHello() { System. out . println(\"hello\"); }}虽然只有194字节,但是里面却使用了String、System、Printstream及object等结构。这里代码量其实已经很小了。如果代码多,引用到的结构会更多!这里就需要常量池了!常量池中有什么?几种在常量池内存储的数据类型包括:数量值、字符串值、类引用、字段引用、方法引用例如下面这段代码:public class MethodAreaTest2 { public static void main(String[] args) { object obj = new 0bject(); }}小总结:常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型。
本地方法栈Native Method Stack
Native MethodInterface(JNI)
第三页
虚拟机栈Java Virtual Machine Stack
内存区域
本地方法接口Native Method Interface(JNI)
Thread3
一、方法区在哪里?答:《Java虚拟机规范》中明确说明:“尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。”但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap (非堆),目的就是要和堆分开。所以,方法区看作是一块独立于Java堆的内存空间。二、Hotspot中方法区的演进1、在jdk7及以前,习惯上把方法区,称为永久代。jdk8开始, 使用元空间取代了永久代。2、本质上,方法区和永久代并不等价。仅是对hotspot而言的。《Java虚拟机规 范》对如何实现方法区,不做统一要求。例如: BEA JRockit/ IBM J9中不存在永久代的概念。 ➢现在来看,当年使用永久代,不是好的idea。导致Java程序更容易0OM (超过-XX :MaxPermSize.上限)3、而到了JDK 8,终于完全废弃了永久代的概念,改用与JRockit、J9- -样在本地内存中实现的元空间(Metaspace)来代替。4、元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代最大的区别在于:元空间不在虚拟机设置的内存中,而是使用本地内存。5、永久代、元空间二者并不只是名字变了,内部结构也调整了。6、根据《Java虚拟机规范》的规定,如果方法区无法满足新的内存分配需求时,将抛出O0M异常。
Prepare
bootstrap Class Loader
Method Area
运行时常量池vs常量池
Linking
Intermediate CodeGenerator
Runtime Data Areas
第二页
第一页
线程共享
Class File字节码文件
NativeMethodStack
Class Loader Subsystem
Execution Engine
Verify
JVM的结构图简图
四、方法区使用
Extension Class Loader
Class File
二、方法区的理解
Target CodeGenerator
Application Class Loader
0 条评论
下一页