运行时数据区
Posted gorgeousbankarian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运行时数据区相关的知识,希望对你有一定的参考价值。
1. 本地方法栈
线程私有native
?就是一个关键字,表示本地的方法。这种方法已经不在Java的管理范围之内,往往是更加底层的C语言库。所以在Java中带 native
?的方法只有声明没有实现。这些方法需要装载和运行,所以存储在本地方法栈中。
举个例子,Java线程中的 start()
?方法的底层就是调用了本地的方法 start0()
?,所以Java中的线程本质上还是归操作系统管理, start()
?后的线程不是立即启动只是进入了就绪态,最终是否运行占用CPU是由操作系统进行调度。
2. PC寄存器
线程私有
存的就是指针(地址),指向方法区中方法的字节码,用来指示下一条要执行的指令代码。就是当前线程所执行字节码的行号指示器。由于 native
?方法并不归Java管理,所以执行 native
?方法时,这个寄存器为空。
由于只是存储地址,所以占用的内存很小,不会发生溢出(OutOfMemory=OOM)错误
3. Java栈
栈管运行,堆管数据
主管Java的方法运行,线程创建时创建,生命周期跟随线程。线程结束栈内存也就释放,不存在垃圾回收。栈内存分配给?8种数据类型 + 引用(对象、方法)
存什么
运行原理
注意点
先进先出,由于 main
?函数是一切程序的入口,所以 main
?函数是最先入栈的,即栈底永远都是 main
?函数。
图示有两个栈,栈顶就是当前要执行的方法,当前方法执行完后根据父帧信息准备执行下一个方法,自己就出栈释放空间。
栈溢出
栈溢出是错误,这个可以从API中得到证实:Exception in thread java.lang.StackOverflowErro
4. 方法区
存什么
- 存储类的模板信息(大Class)。
类的模板信息包括类所有的资源,即所有带 static
?关键字的东东;不带 static
?关键字的是属于某个实例对象的,应存在Java堆中!
类加载器从磁盘读出类文件后,通过类加载器classLoader将类的信息存入方法区,之后实例化就是根据方法区中的类信息来刻画。
- 运行时常量池,垃圾回收主要就是针对常量池的回收和类的卸载。当常量池满后会出现OOM****。
类信息 + 普通常量 + 静态常量 + 编译器编译后的代码等等
逻辑上方法去为堆的一个部分,但是它是Non-Heap(非堆),和堆是不一样的!
实例化
方法区规范 obj = new 原空间; java8
方法区规范 obj = new 永久代; java7
5. Java堆
线程共享 存在垃圾回收(主要)
So important 另开一篇
栈、堆、方法区交互
在方法中如果要用一个变量new一个对象,那么就会先通过双亲委派的方法加载相应的类,之后类的模板信息存在方法区中。根据方法区中的模板,Java堆中实例化一个对象,之后将对象的引用返回到栈,存到变量中。
对于HotSpot版本的JVM,是通过指针指向Java堆来访问对象;Java堆中存放实例的数据,通过指针指向方法区中类的元数据。这个所谓的元数据就是描述类数据的数据,就是大Class。
以上是关于运行时数据区的主要内容,如果未能解决你的问题,请参考以下文章