JVM(Java Virtual Machine)(上)

简介: JVM(Java Virtual Machine)(上)

🔎内存区域划分


JVM 是一个应用程序

在启动时, 会向操作系统申请内存空间

根据不同的需求, 将空间分割成不同的部分, 每个部分的功能各不相同

(类似于我们的房子, 根据不同的需求, 将房子的空间进行分割, 一部分成为了卧室, 一部分成为了厨房…)

  • JVM 将内存区域划分为5个部分
  • Native Method Stacks(本地方法栈)
  • Program Counter Register(程序计数器)
  • JVM Stacks(虚拟机栈)
  • Heap(堆区)
  • Metaspace(元数据区, 也称为方法区)


注意🍭

此处所指的,指代的是JVM中的内存空间

并非数据结构中的,


Program Counter Register(程序计数器)


程序计数器

记录当前线程执行到哪个指令

(程序计数器是很小的一块内存区域)

Native Method Stacks(本地方法栈)


Native 表示 JVM 内部的 C++ 代码

本地方法栈

调用 Native 方法(JVM 内部的方法)时准备的栈空间

JVM Stacks(虚拟机栈)


虚拟机栈

调用 Java 代码时准备的栈空间

栈空间内部包含很多的元素(每个元素表示一个方法)

每一个元素又称为是一个栈帧

  • 栈帧包含
  • 方法的入口
  • 方法的参数
  • 返回地址
  • 局部变量

区分虚拟机栈与本地方法栈🍭

  • 对于本地方法栈, 存储的是Native方法(C++代码)之间的调用关系
  • 对于虚拟机栈, 存储的是方法(Java代码)之间的调用关系
  • 方法的调用, 具有后进先出的特点, 此处的栈也是后进先出

方法的调用, 后进先出

⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇

public static void main(String[] args) {
  System.out.println(testAndVerify());
}
private static String testAndVerify() {
  return "welcome to bibubibu's blog!";
}

栈是线程私有的🍭

对于栈是线程私有的这句话, 并不是足够的准确(个人理解)

私有表示的意思是我的东西, 你不能碰

类似于这台笔记本是我私有的, 你不能碰我的笔记本

但对于一个线程的内容来说, 另一个线程可以通过变量捕获的方式获取

t1 线程通过变量捕获方式访问 main 线程的局部变量 locker

⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        Object locker = new Object();
        Thread t1 = new Thread(() -> {
            try {
                System.out.println("wait开始");
                synchronized(locker) {
                    locker.wait();
                }
                System.out.println("wait结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
  }     
}   

Heap(堆区)


堆区是 JVM 内存空间的最大区域

通常 new 出来的对象都是存储在堆

Metaspace(元数据区)


元数据区, 也称为方法区

即 Meta, 表示属性

元数据区

主要存储类对象, 常量池, 静态成员

这里所说的类对象不是 A a = new A();

而是类似于对象的图纸, 描述了该对象的属性

类对象

⬇⬇⬇⬇⬇

总结


名称 描述
JVM(Java 虚拟机) 每个进程有一份
Program Counter Register(程序计数器) 每个线程有一份
Native Method Stacks(本地方法栈) 每个线程有一份
JVM Stacks(虚拟机栈) 每个线程有一份
Heap(堆区) 每个进程有一份
Metaspace(元数据区) 每个进程有一份
  • 局部变量默认存储在栈
  • 普通成员变量默认存储在堆
  • 静态成员变量默认存储在元数据区(方法区)

🔎类加载


类加载

将 .class 文件, 从文件(硬盘)加载到内存(元数据区)

.java 通过 javac 编译生成 .class

  • 类加载的步骤
  • 加载(Loading)
  • 连接(Linking)
  • 验证(Verfication)
  • 准备(Preparation)
  • 解析(Resolution)
  • 初始化(Initialization)

类加载的流程


加载


找到 .class 文件, 打开文件, 读取文件(将文件内容读取至内存中)

验证


检查 .class 文件的格式是否正确

  • .class 是一个二进制文件, 其格式有着严格的说明
  • 官方提供的 JVM 规范文档详细描述了 .class 的格式


准备


为类对象分配内存空间(此时内存初始化为全0)

静态成员变量的值也就被设为0

解析


初始化字符串常量, 将符号引用转为直接引用

符号引用转为直接引用🍭

  • 字符串常量包括
  • 内存空间, 存储该字符串的实际内容
  • 引用, 存储内存空间的起始地址

类加载之前

字符串常量位于 .class 文件中

此时的引用记录的并非是字符串常量的真正地址, 而是字符串常量在文件中的"偏移量"(符号引用)

类加载之后

字符串常量位于内存中(即字符串常量拥有了内存地址)

此时的引用记录的才是真正的内存地址(直接引用)

相关文章
|
3月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
292 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
4月前
|
存储 运维 Kubernetes
Java启动参数JVM_OPTS="-Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError"
本文介绍了Java虚拟机(JVM)常用启动参数配置,包括设置初始堆内存(-Xms512m)、最大堆内存(-Xmx1024m)及内存溢出时生成堆转储文件(-XX:+HeapDumpOnOutOfMemoryError),用于性能调优与故障排查。
422 0
|
6月前
|
存储 监控 算法
Java程序员必学:JVM架构完全解读
Java 虚拟机(JVM)是 Java 编程的核心,深入理解其架构对开发者意义重大。本文详细解读 JVM 架构,涵盖类加载器子系统、运行时数据区等核心组件,剖析类加载机制,包括加载阶段、双亲委派模型等内容。阐述内存管理原理,介绍垃圾回收算法与常见回收器,并结合案例讲解调优策略。还分享 JVM 性能瓶颈识别与调优方法,分析 Java 语言特性对性能的影响,给出数据结构选择、I/O 操作及并发同步处理的优化技巧,同时探讨 JVM 安全模型与错误处理机制,助力开发者提升编程能力与程序性能。
Java程序员必学:JVM架构完全解读
|
7月前
|
监控 Java Unix
6个Java 工具,轻松分析定位 JVM 问题 !
本文介绍了如何使用 JDK 自带工具查看和分析 JVM 的运行情况。通过编写一段测试代码(启动 10 个死循环线程,分配大量内存),结合常用工具如 `jps`、`jinfo`、`jstat`、`jstack`、`jvisualvm` 和 `jcmd` 等,详细展示了 JVM 参数配置、内存使用、线程状态及 GC 情况的监控方法。同时指出了一些常见问题,例如参数设置错误导致的内存异常,并通过实例说明了如何排查和解决。最后附上了官方文档链接,方便进一步学习。
974 4
|
8月前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
380 29
JVM简介—1.Java内存区域
|
10月前
|
存储 监控 算法
Java JVM 面试题
Java JVM(虚拟机)相关基础面试题
261 4
|
11月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
11月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
11月前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
295 27
|
12月前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
271 28