Java 虚拟机详解

简介: Java 虚拟机详解

JVM 整体结构


0a2653c851af460fa595bd959398a8f1.png

垃圾回收,通常称为 GC 。


类加载器:

2d65d23f6d4748949b924e4057485923.png

箭头指向的就是对应类加载器需要加载的 文件。


前两个类加载器 加载的是我们 jdk 中特定路径下的 jar 包


第三个加载的是应用程序中的 类


可以自定义的 ClassLoader


类加载器 指的就是 ClassLoader ,class 被 ClassLoader 加载后就会存储到内存空间中,内存空间又被分为 方法区,Java 堆,java栈,方法本地栈。这四个区域用来存储 class 不同的部分。


Java 代码的编译和类加载的过程


编译流程:源代码 —— 词法分析器 —— Token 流 —— 语法分析器 —— 语法树/抽象语法树 —— 语义分析器 —— 注解抽象语法树 —— 字节码生成器 —— JVM 字节码


类加载过程


0a2653c851af460fa595bd959398a8f1.png


加载:获取class字节码文件并且载入到 JVM 内存里


验证:检查读入的字节流是否符合 JVM 规范的描述,不会造成安全错误


准备:主要是为类变量(注意:不是实例变量)分配内存,并且赋予初值


分析:把类的常量池中所有的符号引用改为直接引用


初始化:执行静态初始化程序,把静态变量初始化成指定值,如果有静态代码块,则也会执行。


内存管理和垃圾回收


java 将内存区域分为了四个区域,方法区,栈区,堆区,本地方法栈


java 栈区


他作用是用来存放java 方法执行时的所有数据,栈区就是用来描述 java 方法执行的完整内存模型。 组成:由栈帧组成,一个栈帧代表一个方法的执行,每个方法从调用到执行完的过程就对应一个栈帧在虚拟机中入栈到出栈。例如:从 在 a 方法中调用 b 方法,a 方法的栈帧首先入栈,然后执行到调用 b 方法的代码时会创建一个 b 方法的栈帧入栈,然后执行 b 方法,b 方法执行完后随即对应的栈帧出栈,就会回到 a 调用 b 方法的地方,然后 a 继续执行,执行完后 a 方法的栈帧会被从java栈区弹出。栈帧中包含的内容:局部变量表,栈操作数,动态链接,方法出口。


本地方法栈


作用:本地方法栈是专门为 native 方法服务的 ,和 java 栈区差不多


方法区


存储被虚拟机加载的类信息,常量,静态变量 等一系列编译期所要保存的数据,方法区是永远占据内存的。


堆区


作用:所有通过 new 创建的对象的内存都是在堆中进行分配


特点:是虚拟机中最大的一块内存,是 GC 要回收的部分


堆区内存:


垃圾收集


垃圾收集算法:


引用计数法,对象被引用后 计数器+1,取消引用后 -1,当计数器 为0 ,则对象为 0 后 为垃圾对象。缺陷:如 对象 A ,B ,A 引用了 B ,B 引用了 A ,此时没有别的引用 A B ,则这两个已经是垃圾了。但是不能够被回收。


可达性算法,也叫做根搜索算法,从 GC Root 节点开始算起,从这个节点开始寻找所有的引用节点,找到这个节点以后继续寻找这个节点的引用,当所有的节点找到后,剩余的节点则就是没有被引用的节点。这些就是不可达的节点,jvm 就会认为这些是垃圾对象。下面根据图来看一下:

0a2653c851af460fa595bd959398a8f1.png

如 objD 和 objE 没有可达的路径,所以会被回收


引用类型


强引用,弱引用,软引用,虚引用


下面看一下弱引用创建方式:


//强引用
Object obj = new Object();
//弱引用
WeakReference<Object> weak = new WeakReference<>(obj);
//ob 指向 null 
obj = null;
weak.get(); //获取 弱引用对象,弱引用在没有被对象引用就会被回收。需要注意一下


垃圾回收


标记清除法:


0a2653c851af460fa595bd959398a8f1.png


从根集合遍历所有的引用,从根集合可以遍历到 A ,从 A 可以遍历到C,但是 B 成为了一个不可达的引用,B 对象就会标记为垃圾对象。最后被回收。缺点,会造成内存碎片


复制算法:

2d65d23f6d4748949b924e4057485923.png

把可达的进行复制,复制完了之后把原来的对象全部进行回收,缺点,需要一个交换内存


标记整理算法:


第一个阶段扫描并标记不可达的对象,第二个阶段扫描整个空间并进行整理,在整理的过程中清除标记的对象


垃圾回收触发方式


java 虚拟机无法为新的对象分配内存空间了


手动 System.gc() 方法


底优先级的 GC 线程被运行时就会执行 GC


Dalvik 与 JVM 的不同


执行文件不同,一个是 calss 文件 ,一个是 dex 文件


类加载的系统与 JVM 区别较大的


可以同时存在多个 DVM


dalvik 是基于寄存器的,而 JVM 是基于栈的


ART 比 Dalvik 有哪些优势


DVM 使用 JIT 将字节码转换 机器码,效率低


ART 采用了 AOT 预编译技术,执行速度快,AOT 在应用程序安装的时候将字节码转换成了本地机器码。这个执行的很快


JVM 是基于栈的


ART 比 Dalvik 有哪些优势


DVM 使用 JIT 将字节码转换 机器码,效率低


ART 采用了 AOT 预编译技术,执行速度快,AOT 在应用程序安装的时候将字节码转换成了本地机器码。这个执行的很快


ART 会占用更多的应用安装时间和存储空间


相关文章
|
21天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
2月前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
5月前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
79 0
|
3月前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
131 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
4月前
|
Java
Java常见JVM虚拟机指令(47个)
Java常见JVM虚拟机指令(47个)
80 3
Java常见JVM虚拟机指令(47个)
|
5月前
|
监控 Oracle Java
(一)JVM成神路之初识虚拟机 - 探寻Java虚拟机的前世今生之秘
JVM(Java Virtual Machine)Java虚拟机的概念大家都不陌生,Java之所以可以做到“一次编译,到处运行”的跨平台性,其根本原因就在于JVM。JVM是建立在操作系统(OS)之上的,Java虚拟机屏蔽了开发人员与操作系统的直接接触,我们在通过Java编写程序时,只需要负责编写Java代码即可,关于具体的执行则会由JVM加载字节码后翻译成机械指令交给OS执行。
101 1
|
4月前
|
Java 数据安全/隐私保护 Windows
【Azure Developer】使用Java代码启动Azure VM(虚拟机)
【Azure Developer】使用Java代码启动Azure VM(虚拟机)
|
4月前
|
存储 Java API
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
|
5月前
|
存储 Ubuntu Java
【Linux】已解决:Ubuntu虚拟机安装Java/JDK
【Linux】已解决:Ubuntu虚拟机安装Java/JDK
198 1
|
5月前
|
监控 算法 Java
深入理解Java虚拟机:内存管理与性能优化
在Java的世界里,虚拟机(JVM)是幕后的守护者,它默默地支撑着每一个字节码的运行。本文将揭开JVM的神秘面纱,探讨其内存管理机制及如何通过调优提升应用性能。从堆内存的分配到垃圾回收的策略,再到实践中的性能监控与调优技巧,我们将一同走进JVM的内部世界,学习如何让我们的Java程序跑得更快、更稳。