JVM知识点整理
本文最后更新于:2 年前
JVM知识点的综合整理。
JVM及JVM的位置
JVM
Java虚拟机(英语:Java Virtual Machine,缩写为JVM)。JVM是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码字节码(.class文件),就可以在多种平台上(操作系统windows,linux,MAC)不加修改地运行。通过对中央处理器CPU所执行的软件实现,实现能执行编译过的Java程序码(Applet]与应用程序)。
是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JVM的位置
它是整个java实现跨平台的最核心的部分,由Java文件编译来的class文件,只有经过虚拟机解释才能被操作系统执行。
一次编译,多处运行:JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的class文件(字节码),就可以在多种平台上不加修改地运行。
JVM,JRE,JDK的关系:JDK包含JRE,JRE包含JVM。
JVM高频面试题
执行代码可以分为编译执行和解释执行。解释执行指的是边解释边运行代码。编译执行指的是先编译,后执行。
参考
JVM(Java虚拟机)
Java程序运行的底层平台,与==Java支持库==一起构成了Java程序的执行环境。
JRE = JVM + Java标准库
JDK= JRE + Java开发诊断工具
JVM的跨平台和跨语言
跨平台
一个Java类,可以在不同的操作系统(windows、Linux、MACOS)上执行,结果都一样。
跨语言(语言无关性)
与语言解耦。
JVM运行不是翻译Java文件,而是识别class文件。
可以运行Java、Groovy、Kotlin、Scala产生的class文件。
JVM的体系结构
其中线程独占区不会有垃圾回收.
JVM调优几乎都在线程共享区,其中大部分都在堆.
类的加载过程:JVM将javac编译好的class字节码文件加载到内存中,并对该数据进行验证、解析和初始化、形成JVM可以直接使用的JAVA类,最终回收(卸载)的过程。
栈的空间大小远远小于堆。
栈也叫栈内存。
相关的各组件
类加载器(ClassLoader):
负责加载class文件(classs文件在文件开头有特定的文件标识):将class文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构;
ClassLoader只负责加载class文件的加载,至于它是否可以运行,则由Execution Engine决定。
方法区(Method Area):
- 方法区是各个线程共享的内存区域;
- 方法区用于存储已被虚拟机加载的类的模板信息、常量、静态变量等;
- 虽然Java虚拟机规范把方法区描述为堆的一部分,但是他还有个别名叫做Non-heap(非堆),目的应该是与Java堆区分开来;
- 根据Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常;
- 垃圾收集在这个区域是比较少出现的,但并非数据进入了方法区就如永久代的名字一样永久存在了。
- 这区域的内存回收目标主要是针对常量池的回收和类型的卸载。
PC寄存器(程序计数器):
- 每个线程都有一个程序计数器,是线程私有的;
- 就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,既将要执行的指令代码),由执行引擎读取下一条指令。
- 是一个非常小的内存空间,几乎可以忽略不记;
- 它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。
- 如果执行的是一个Native方法,那这个计数器是空的;
- 用以完成分支、循环、跳转、异常处理、线程恢复等基础功能。
- 不会发生内存溢出OOM错误。
虚拟机栈(Vm Stack)
虚拟机栈为虚拟机执行Java方法(也就是字节码)服务。
主管 Java 程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放。
栈不存在垃圾回收问题,生命周期和线程一致,是线程私有的。
8种基木类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配。
本地方法栈(Native Method Stacks):
- 本地方法栈为虚拟机使用到的本地Native方法服务‘;
- 有的虚拟机(例如Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一(在虚拟机规范中对本地方法栈中的使用方法、语言、数据结构并没有强制规定,因此具体的虚拟机可以自由实现它)
- 会抛出StackOverFlowError和OutOfmMemoryError异常。
Java堆(Java Heap):
- Java虚拟机管理内存中的最大一块;
- Java堆是所有线程共享的内存管理区域。此内存区域
- 唯一目的就是存放对象的实例,几乎所有对象实例都在堆中分配内存。(这一点在Java虚拟机规范中的描述是:所有对象实例以及数组都要在堆上分配,但是随着JIT编译器的发展与逃逸技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也不是变的)。
思考
虚拟机栈与本地方法栈的区别:
两者类似,区别是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,本地方法栈则为虚拟机使用到的本地Native方法服务‘;
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!