详细了解JVM运行时内存

详细了解JVM运行时内存1.程序计数器概念程序计数器也叫作PC寄存器,是一块很小的内存区域,可以看做是当前线程执行的字节码的行号指示器 。字节码的解释工作就是通过改变程序计数器里面的值来获得下一条需要执行字节码的指令 。
特点

  • Pc寄存器表现为一块内存,功能是存放伪指令,确切的说是存放的将要执行指令的地址 。
  • 当虚拟机正在执行的是一个native方法时,JVM的PC寄存器存储的值是undefined 。
  • 程序计数器是线程私有的,它的生命周期和线程一样,每个线程只有一个 。这也是为了保证多线程下,线程切换后能恢复到正确的执行位置 , 所以每个线程需要独立的程序计数器,相互隔离互不影响 。
  • 此区域是唯一一个没有OOM情况的区域 。
图例
详细了解JVM运行时内存

文章插图
2.虚拟机栈概念JAVA虚拟机栈的生命周期和线程相同,他也是线程私有的,每一个线程有自己独立的虚拟机栈 。他用来存储栈帧,程序运行时,每一个方法被调用执行时都会创建一个栈帧,用来存储局部变量表、操作数栈、动态链接、方法出口等信息 。每一个方法从调用到执行完就对应着一个栈帧在虚拟机中从入栈到出栈的过程 。
图例演示
详细了解JVM运行时内存

文章插图
栈帧栈帧是支持虚拟机方法调用和执行的数据结构 。栈帧中存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息 。每一个方法的调用和执行完成都对应着一个栈帧从虚拟机栈中入栈到出栈的过程 。
详细了解JVM运行时内存

文章插图
设置虚拟机栈的大小-Xss为JVM启动时的每个线程分配的内存大小,也就是可以设置线程栈的大小 。
-Xss1m# 单位为MB-Xss1024k#单位为KB-Xss1048576#字节大小局部变量表【详细了解JVM运行时内存】局部变量表是一组变量值存储空间,用于存放方法的参数和方法内定义的局部变量 。
详细了解JVM运行时内存

文章插图
操作数栈操作数栈是一个后入先出栈(LIFO) 。随着方法执行和字节码指令的执行,会从局部变量表或者对象实例的字段中复制常量或者变量写到操作数栈 , 再随着计算的进行会将栈中的元素出栈到局部变量表或者返回给方法调用者 。
动态链接java虚拟机中,每一个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,持有这个引用的目的为了支持方法调用过程中的动态链接 。动态链接的作用:将符号引用转换为直接引用 。
方法返回地址方法返回地址存放调用该方法的PC寄存器的值 。一个方法的结束,有两种方式:正常地执行完成,出现未处理的异常非正常的退出 。无论通过哪种方式退出,在方法退出后都返回到该方法被调用的位置 。方法正常退出时,调用者的PC计数器的值作为返回地址,即调用该方法的指令的下一条指令的地址 。而通过异常退出的 , 返回地址是要通过异常表来确定,栈帧中一般不会保存这部分信息 。无论方法是否正常完成,都需要返回到方法被调用的位置,程序才能继续进行 。
3.本地方法栈概念本地方法栈则是为虚拟机使用到的本地(Native) 方法服务,而虚拟机栈是为使用到的java方法服务 。
关于native方法native关键字修饰的Java方法是一个原生态方法,方法对应的实现Java作用范围达不到,而是在用其他编程语言(如C和C++)文件中实现 。Java语言本身不能直接对操作系统底层进行访问和操作,但可以通过JNI接口调用其他编程语言来实现对操作系统底层的访问 。native方法在异地实现,类似抽象方法 , 不能有方法体,要以分号结束 。例如:
详细了解JVM运行时内存

文章插图
本地方法栈特点
  • 本地方法栈加载nativef方法 , 是为了填补java不方便实现的场景产生的 。
  • 虚拟机栈为为虚拟机执行java服务 , 而本地方法栈为了执行虚拟机所使用到的native服务
  • 本地方法栈也是线程私有的,和线程的生命周期是一致的,每个线程都有一个本地方法栈 。
4.堆4.1 堆的总括4.1.1 概念Java堆(Java Heap) 是虚拟机所管理的内存中最大的一块 。Java堆是被所 有线程共享的一块内存区域, 在虚拟机启动时创建 。此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存 。

推荐阅读