虚拟机的前世今生和JVM内存区域
虚拟机的前世今生
- 首先来看下这张图:
HelloWorld.class
为java程序编译后的字节码,JVM为一个小型的操作系统(相当与windows或者你可以理解为linux),接受该字节码,翻译成一个硬件(操作系统)可以识别的机器码
- 常见的JVM实现有以下几种:
- JVM的跨平台与语音无关性:
多种语言均可使用
- JVM整体知识模块
JVM 是一个虚拟化的操作系统,所以除了要虚拟指令之外,最重要的一个事情就是需要虚拟化内存,这个虚拟化内存就是我们马上要讲到的 JVM 的内存区域。
JVM内存区域
JVM—操作系统 java虚拟机,class指令。虚拟内存
- java方法的运行与虚拟机栈
java每开启一个线程时会创建一块独立的空间(线程私有区),里面包含虚拟机栈,本地方法栈和程序计数器。
运行时数据区的定义:Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域
Java 引以为豪的就是它的自动内存管理机制。相比于 C++的手动内存管理、复杂难以理解的指针等,Java 程序写起来就方便的多。 所以要深入理解 JVM 必须理解内存虚拟化的概念。
在 JVM 中,JVM 内存主要分为堆、程序计数器、方法区、虚拟机栈和本地方法栈等。 >同时按照与线程的关系也可以这么划分区域:
线程私有区域:一个线程拥有单独的一份内存区域。
线程共享区域:被所有线程共享,且只有一份。
这里还有一个直接内存,这个虽然不是运行时数据区的一部分,但是会被频繁使用。你可以理解成没有被虚拟机化的操作系统上的其他内存(比如操作 系统上有 8G 内存,被 JVM 虚拟化了 3G,那么还剩余 5G, JVM 是借助一些工具使用这 5G 内存的,这个内存部分称之为直接内存)
- java方法的运行与虚拟机栈
虚拟机栈是线程运行 java 方法所需的数据,指令、返回地址。其实在我们实际的代码中,一个线程是可以运行多个方法的。 比如:
这段代码很简单,就是起一个 main 方法,在 main 方法运行中调用 A 方法,A 方法中调用 B 方法,B 方法中运行 C 方法。
我们把代码跑起来,线程 1 来运行这段代码, 线程 1 跑起来,就会有一个对应 的虚拟机栈,同时在执行每个方法的时候都会打包成一个栈帧。
比如 main 开始运行,打包一个栈帧送入到虚拟机栈。
C 方法运行完了,C 方法出栈,接着 B 方法运行完了,B 方法出栈、接着 A 方法运行完了,A 方法出栈,最后 main
方法运行完了,main 方法这个栈帧就 出栈了。 这个就是 Java
方法运行对虚拟机栈的一个影响。虚拟机栈就是用来存储线程运行方法中的数据的。而每一个方法对应一个栈帧
- 虚拟机栈
栈的数据结构:先进后出(FILO)的数据结构,
虚拟机栈的作用:在 JVM 运行过程中存储当前线程运行方法所需的数据,指令、返回地址。
虚拟机栈是基于线程的:哪怕你只有一个 main() 方法,也是以线程的方式运行的。在线程的生命周期中,参与计算的数据会频繁地入栈和出栈,栈的生 命周期是和线程一样的。 虚拟机栈的大小缺省为 1M,可用参数 –Xss 调整大小,例如-Xss256k。
参数官方文档(JDK1.8):https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
栈帧:在每个 Java 方法被调用的时候,都会创建一个栈帧,并入栈。一旦方法完成相应的调用,则出栈。 栈帧大体都包含四个区域:(局部变量表、操作数栈、动态连接、返回地址)
- 程序计数器
较小的内存空间,当前线程执行的字节码的行号指示器;各线程之间独立存储,互不影响。 (白话文:用来记录程序行号)
- 栈帧执行对内存区域的影响
对 class 进行反汇编 javap–cXXXX.class
字节码助记码解释地址:https://cloud.tencent.com/developer/article/1333540
在 JVM 中,基于解释执行的这种方式是基于栈的引擎,这个说的栈,就是操作数栈
面试:站在操作系统层面解释一下JVM
操作数栈:执行引擎的一个工作区
操作系统:
CPU+缓存+主内存
java版的mini操作系统(JVM):
JVM执行引擎+操作数栈+栈,堆
本文地址:https://blog.csdn.net/weixin_43139183/article/details/109267964
上一篇: 谈谈前端异常捕获与上报
下一篇: 通过反射来剖析类的构成