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 文件中

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

类加载之后

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

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

相关文章
|
1月前
|
Java
jvm复习,深入理解java虚拟机一:运行时数据区域
这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
63 19
jvm复习,深入理解java虚拟机一:运行时数据区域
|
1月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
31 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
25天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
1月前
|
存储 算法 Java
深入理解Java虚拟机(JVM)及其优化策略
【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
41 1
|
1月前
|
安全 Java API
🌟探索Java宇宙:深入理解Java技术体系与JVM的奥秘
本文深入探讨了Java技术体系的全貌,从Java语言的概述到其优点,再到Java技术体系的构成,以及JVM的角色。旨在帮助Java开发者全面了解Java生态,提升对Java技术的认知,从而在编程实践中更好地发挥Java的优势。关键词:Java, JVM, 技术体系, 编程语言, 跨平台, 内存管理。
35 2
|
1月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
41 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
1月前
|
监控 Java
Java的JVM如何优化?
Java的JVM如何优化?
56 3
|
2月前
|
存储 缓存 监控
【Java面试题汇总】JVM篇(2023版)
JVM内存模型、双亲委派模型、类加载机制、内存溢出、垃圾回收机制、内存泄漏、垃圾回收流程、垃圾回收器、G1、CMS、JVM调优
【Java面试题汇总】JVM篇(2023版)
|
2月前
|
安全 前端开发 Java
浅析JVM invokedynamic指令与Java Lambda语法的深度融合
在Java的演进历程中,Lambda表达式无疑是Java 8引入的一项革命性特性,它极大地简化了函数式编程在Java中的应用,使得代码更加简洁、易于阅读和维护。而这一切的背后,JVM的invokedynamic指令功不可没。本文将深入探讨invokedynamic指令的工作原理及其与Java Lambda语法的紧密联系,带您领略这一技术背后的奥秘。
29 1
|
1月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
37 4