你是否也遇到过这些问题?
运行线上系统突然卡死, 系统无法访问, 甚至直接 OOM
想解决线上 JVM GC 问题, 但却无从下手
新项目上线, 对各种 JVM 参数设置一脸懵逼, 直接默认, 然后就 JJ 了
每次面试都要重新背一遍 JVM 的一些原理概念性东西
这段广告语写的好, 趁着在家办公学习下 JVM, 先列出整体知识点
Java 开发都知道 JVM 是 Java 虚拟机, 上学时还用过的 VM 也叫虚拟机, 先比较一波
虚拟机与 Java 虚拟机
所谓虚拟机(Virtual Machine), 就是一台虚拟的计算机. 它是一款软件, 用来执行一系列虚拟计算机指令. 大体上, 虚拟机可以分为系统虚拟机和程序虚拟机.
Visaual Box,VMware 就属于系统虚拟机, 它们完全是对物理计算机的仿真, 提供了一个可运行完整操作系统的软件平台
程序虚拟机的典型代表就是 Java 虚拟机, 它专门为执行单个计算机程序而设计, 在 Java 虚拟机中执行的指令我们称为 Java 字节码指令
JVM 是什么
JVM 是 Java Virtual Machine(Java 虚拟机)的缩写, JVM 是一种用于计算设备的规范, 它是一个虚构的计算机, 是通过在实际的计算机上仿真模拟各种计算机功能来实现的.
Java 虚拟机是二进制字节码的运行环境, 负责装载字节码到其内部, 解释 / 编译为对应平台的机器指令执行. 每一条 Java 指令, Java 虚拟机规范中都有详细定义, 如怎么取操作数, 怎么处理操作数, 处理结果放在哪里.
特点
一次编译, 到处运次(跨平台)
自动内存管理
自动垃圾回收功能
字节码
我们平时所说的 java 字节码, 指的是用 java 语言编写的字节码, 准确的说任何能在 jvm 平台上执行的字节码格式都是一样的, 所以应该统称为 jvm 字节码.
不同的编译器可以编译出相同的字节码文件, 字节码文件也可以在不同的 jvm 上运行.
Java 虚拟机与 Java 语言没有必然的联系, 它只与特定的二进制文件格式 --Class 文件格式关联, Class 文件中包含了 Java 虚拟机指令集 (或者称为字节码, Bytecodes) 和符号集, 还有一些其他辅助信息.
Java 代码执行过程
JVM 的位置
JVM 是运行在操作系统之上的, 它与硬件没有直接的交互.
JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK).JDK 物理存在, 是 Java Language,Tools,JRE 和 JVM 的一个集合.
JVM 整体结构
JVM 的架构模型
Java 编译器输入的指令流基本上是一种基于栈的指令集架构, 另外一种指令集架构则是基于寄存器的指令集架构.
两种架构之间的区别:
基于栈式架构的特点
设计和实现更简单, 适用于资源受限的系统;
避开了寄存器的分配难题, 使用零地址指令方式分配;
- Classfile /Users/starfish/workspace/myCode/starfish-learning/starfish-learn/target/classes/priv/starfish/jvm/JVM1.class
- Last modified 2020-2-7; size 487 bytes
- MD5 checksum 1a9653128b55585b2745270d13b17aaf
- Compiled from "JVM1.java"
- public class priv.starfish.jvm.JVM1
- SourceFile: "JVM1.java"
- minor version: 0
- major version: 52
- flags: ACC_PUBLIC, ACC_SUPER
- Constant pool:
- #1 = Methodref #3.#22 // java/lang/Object."<init>":()V
- #2 = Class #23 // priv/starfish/jvm/JVM1
- #3 = Class #24 // java/lang/Object
- #4 = Utf8 <init>
- #5 = Utf8 ()V
- #6 = Utf8 Code
- #7 = Utf8 LineNumberTable
- #8 = Utf8 LocalVariableTable
- #9 = Utf8 this
- #10 = Utf8 Lpriv/starfish/jvm/JVM1;
- #11 = Utf8 main
- #12 = Utf8 ([Ljava/lang/String;)V
- #13 = Utf8 args
- #14 = Utf8 [Ljava/lang/String;
- #15 = Utf8 i
- #16 = Utf8 I
- #17 = Utf8 j
- #18 = Utf8 k
- #19 = Utf8 MethodParameters
- #20 = Utf8 SourceFile
- #21 = Utf8 JVM1.java
- #22 = NameAndType #4:#5 // "<init>":()V
- #23 = Utf8 priv/starfish/jvm/JVM1
- #24 = Utf8 java/lang/Object
- {
- public priv.starfish.jvm.JVM1();
- flags: ACC_PUBLIC
- Code:
- stack=1, locals=1, args_size=1
- 0: aload_0
- 1: invokespecial #1 // Method java/lang/Object."<init>":()V
- 4: return
- LineNumberTable:
- line 3: 0
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 5 0 this Lpriv/starfish/jvm/JVM1;
- public static void main(java.lang.String[]);
- flags: ACC_PUBLIC, ACC_STATIC
- Code:
- stack=2, locals=4, args_size=1
- 0: iconst_1 // 冒号前的数字表示程序计数器的数, 常量 1 入栈
- 1: istore_1 // 保存到 1 的操作数栈中, 这里的 1 表示操作数栈的索引位置
- 2: iconst_2
- 3: istore_2
- 4: iload_1 // 加载
- 5: iload_2
- 6: iadd // 常量出栈, 求和
- 7: istore_3 // 存储到索引为 3 的操作数栈
- 8: return
- LineNumberTable:
- line 6: 0
- line 7: 2
- line 8: 4
- line 9: 8
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 9 0 args [Ljava/lang/String;
- 2 7 1 i I
- 4 5 2 j I
- 8 1 3 k I
- MethodParameters: length = 0x5
- 01 00 0D 00 00
- }
来源: https://www.cnblogs.com/lazyegg/p/12340790.html