快速入门JVM,只看这一篇就够了(三)

97 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第45天,点击查看活动详情

之前在其他平台发表过的文章,今天分享在掘金,跟大家一起学习~

5.Native,本地方法区/本地方法接口

普通的类当中不能有只声明为实现的方法,但是可以有用native修饰的只声明未实现的方法。 无法通过编译,报错:

在这里插入图片描述

用native修饰可以完成: 在这里插入图片描述

声明了native的方法就是调用底层操作系统或者C/C++的函数了,与Java没有任何关系了。

Native Interface本地接口: 本地接口的作用是融合不同的编程语言为Java所有,Java调用C/C++程序,于是就在内存中专门开辟了一块区域处理标记为native的代码,它的具体做法是Native Method Stack中登记native方法,在Execution Engine执行时加载Native Libraies.

Native Method Stack 具体做法就是Native Method Stack中等级native方法,在Execution Engine执行时加载本地方法库。

6.PC寄存器,也即程序计数器

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记, 这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。如果执行的是一个Native方法,那这个计数器是空的。用以完成分支,循环,跳转,异常处理,线程恢复等基础功能,不会发送内存溢出(Out Of Memory)错误。

7.方法区(Method Area,线程共享,存在垃圾回收)

各线程共享的运行时内存区域,它存储了每一个类的结构信息,例如运行时的常量池、字段和方法数据、构造函数和普通方法的字节码内容。不同虚拟机的实现是不一样的,最典型的就是永生代(PermGen Space)和元空间(Metaspace)。 但是,实例变量存在堆内存中,与方法区无关!

8.栈区(Stack Area)

总的一句话,栈管运行,堆管存储。 栈内存,主管Java程序的运行,是在线程创建时创建,它的生命周期是跟随线程的生命周期的,线程结束时栈内存就释放,不存在垃圾回收的问题,且为线程私有的。 8种基本数据类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配的。 栈帧中主要保存3类数据:

  • 本地变量:输入参数和输出参数以及方法内的变量
  • 栈操作:记录出栈、入栈的操作
  • 栈帧数据:包括类文件、方法等

当Java中的方法,被JVM处理时,其就成为了栈帧 在这里插入图片描述 以下图片更加方便理解: 在这里插入图片描述 如果递归调用没有递归的结束条件,就会抛出Stack Overflow Error错误。 重要:栈+堆+方法区的交互关系: 在这里插入图片描述 在HotSpot虚拟机中,是使用指针的方式来访问对象:Java堆中会存放访问类元数据的地址,reference存储的就直接是对象的地址。 比如Student std=new Student(),std存放在栈区,Student对象存放在堆区,用来造Student对象的模板在方法区,三者之间在HotSpot虚拟机中通过指针来引用。

9.堆区(Heap)

在JDK7之前,堆内存逻辑上分为:新生区+养老区+永久区 JDK8以后,堆内存逻辑上分为:新生区+养老区+元空间

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述