定义:Java Virtual Machine -java程序的运行环境(java二进制字节码的运行环境)
好处:
一次编写,到处运行
自动内存管理,垃圾回收
数组下标越界检测
多态
比较:jvm/jre/jdk

常见的JVM:HotSpot
学习路线👇

内存结构
1.程序计数器
定义:

Program Counter Register 程序计数器(寄存器)
(程序计数器)作用:记住下一条jvm指令的执行地址

特点:
线程私有的
不会存在内存移除
2. 虚拟机栈
栈------线程运行需要的内存空间
栈帧------每个方法运行时需要的内存
一个栈由多个栈帧组成
每个线程运行时需要的内存,称为虚拟机栈
每个栈由多个栈帧组成,每个栈帧对应着每次方法调用时所占的内存
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

问题:
1.垃圾回收是否涉及栈内存?
垃圾回收只回收堆内存的无用项。不需要对栈内存进行垃圾回收的处理。
2.栈内存分配越大越好吗?
栈并不是越大越好,大只是更多次的方法递归调用。并不能增加效率,反而会减少线程数量。
3.方法内的局部变量是否线程安全?
如果方法内局部变量没有逃离方法的作用范围,他是线程安全的。
如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全。
栈内存溢出
栈帧过多导致栈内存溢出(无限递归)
栈帧过大导致栈内存溢出
线程运行诊断
案例1:cpu占用过多
定位,用top定位哪个进程对cpu的占用过高
ps H -eo pid,tid,%cpu|grep 进程id(用ps命令进一步定位是哪个线程引起的cpu占用过高)
jstack 进程id(可以根据线程id找到有问题的线程,进一步定位到问题代码的源码行号)
案例2:程序运行很长时间没有结果
jstack 进程id,可能是多个线程发生了死锁
3.本地方法栈

Java虚拟机调用本地方法,需要给这些本地方法提供内存。
本地代码,不是用java编写的。Java有限制,不能直接和操作系统打交道,就需要由c或c++编写的本地方法,来真正的和操作系统底层的API打交道。native
4.堆
通过new关键字,创建的对象都会使用堆内存
特点:
它是线程共享的,堆中对象都需要考虑线程安全的问题。
有垃圾回收机制。
堆内存溢出
对象被当成垃圾回收的条件是没有人使用他,如果不断地产生对象,而产生的新对象永远有人在使用,这样的对象达到一定数量,就会导致堆内存耗尽。
堆内存诊断
工具:

20_堆_内存诊断_jconsole_哔哩哔哩_bilibili
21_堆_内存诊断_jvirsualvm_哔哩哔哩_bilibili
5.方法区
方法区是所有Java虚拟机线程共享的区,它存储了跟类相关的区(成员变量、方法数据、成员方法构造器方法以及他们的代码)。
方法区在虚拟机启动时被创建,逻辑上是堆的组成部分。?
