运行时数据区

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。

技术图片

以上是关于运行时数据区的主要内容,如果未能解决你的问题,请参考以下文章

运行时数据区(总览)

JVM-运行时数据区

Jvm,运行时数据---独占区---程序计数器

轻松保存重复多用的代码片段

20张图助你了解JVM运行时数据区,你还觉得枯燥吗?

JVM学习笔记五:运行时数据区之本地方法栈