jVM探究
请你谈谈你对jvm的理解?java8虚拟机和之前的变化更新
什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
JVM的常用调优参数有哪些
内存快照如何抓取,怎么分析Dump文件?
谈谈JVM中,类加载器你的认识?
1.JVM的位置
JVM ->操作系统 -> 硬件系统
2.JVM的体系结构
3.类加载器
作用: 加载class文件
1.虚拟机自带的加载器
2.启动类(根) 加载器
3.扩展类加载器
4.应用程序(系统类)加载器
4.双亲委派机制
1.类加载器收到类加载的请求
2.将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器
3.启动加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则抛出异常
通知子加载器进行加载
4.重复步骤3
5.沙箱安全机制
–
6.Native
package jvm;
public class Demo {
public static void main(String[] args) {
new Thread(() ->{
},"my thread name").start();
}
//native: 凡是带了native关键字的,说明java的作用范围达不到了,回去调用底层c语言的库
//会进入本地方法栈
//调用本地方法本地接口 JNI
//JNI作用:扩展java使用,融合不同的编程语言为java所用
//它在内存区域中专门开辟了一块区域: Native Method Stack 登记native方法
//在最终执行的时候,加载本地方法通过JNI
private native void start0;
}
7.PC寄存器
程序计数器 : Program Counter Register
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码,在执行引擎读取下一条命令,是一个非常小的内存空间,几乎可以忽略不计
8.方法区
Method Area方法区
方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享空间
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关
9.栈
数据结构
栈:先进后出、后进先出
队列: 先进先出(FIFO)
生命周期和线程同步,线程结束,栈内存就释放,对于栈来说,不存在垃圾回收的问题
一旦线程结束,栈就over了
栈:8大基本类型+对象引用+实例方法
栈运行原理: 栈祯
栈+堆+方法区 :交互关系
10.三种JVM
- Sun公司
HotSpot
Java™ SE Runtime Environment (build 1.8.0_331-b09) - BEA
JRockit
- IBM.
J9VM
11.堆
Heap,一个jvm只有一个堆内存,堆内存的大小是可以调节的
类加载器读取了类文件后,一般会把什么东西放到堆中? 类、方法、常量、变量、、保存我们所引用的真实对象
堆内存中还要细分为三个区域
- 新生区
- 养老区
- 永久区
在JDK8以后,永久存储区改了个名字 ----元空间
12.新生区、老年区
- 类: 诞生和生长的地方
- 伊甸园,所有的对象都是在伊甸园区new 出来的
真理: 经过研究,99%的对象都是临时对象!
13.永久区
- Jdk6 之前: 永久代,常量池是在方法区
- jdk7 :永久代,但是慢慢的退化了,
去永久代
,常量池在堆中 - jdk8 :无永久代,常量池在元空间
14.堆内存调优
// OOM:
//1.尝试扩大堆内存看结果
//2.分析内存,看一下那个地方出现了问题
// -Xms1024m -Xmx1024m。-XX:+PrintGCDEtails
/*
元空间逻辑上存在,物理上不存在
*/
MAT、Jprofiler–内存快照分析工具
- 分析Dump内存文件,快速定位内存泄漏
- 获得堆中的数据
- 获得大的对象
package jvm;
import java.util.ArrayList;
//-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
public class Demo02 {
byte[] array= new byte[1*1024*1024]; //1m
public static void main(String[] args) {
ArrayList<Demo02> list = new ArrayList<>();
int count =0;
try {
while (true){
list.add(new Demo02());
count =count+1;
}
}catch (Error e){
System.out.println(count);
}
}
}
15.GC
垃圾回收机制
JVM在进行GC回收时,大部分的时候,回收都是在新生代
-
新生代
-
幸存区 (from,to)-- 谁空谁是to
-
老年代
GC两种类型:轻GC(普通GC),重GC(全局GC)
题目:
- JVM的内存模型和分区 -详细到每个区做什么
- 堆里面的分区有哪些? Eden,from, to,老年代
- GC的算法有哪些 :标记清除法,标记整理,复制算法,引用计数法:
- 轻GC和重GC分别在什么时候执行
15.1:常用算法
引用计数法
不常用
复制算法–年轻代
- 好处: 没有内存的碎片
- 坏处 : 浪费了内存空间
复制算法最佳使用场景:对象存活度较低的时候—新生代
标记清除算法
- 优点 : 不需要额外的空间
- 缺点 : 两次扫描,严重浪费时间,会产生内存碎片
标记压缩算法
总结:
内存效率 : 复制算法>标记清除>标记压缩 (时间复杂度)
内存整齐度 : 复制算法 =标记压缩算法 >标记清除算法
内存利用率 : 标记压缩 = 标记清除 >复制算法
难道没有最优的算法?没有
没有最好的算法,只有最合适的算法
年轻代:
- 存活率低
- 复制算法
老年代:
- 区域大,存活率高
- 标记清除算法(内存碎片不是太多)+标记压缩算法
16.JMM
java Memory model java内存模型
1、什么是JMM
2、它是干嘛的?
作用:缓存一致性协议,用于定义数据读写的规则
JMM定义了线程工作内存和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)
中,每个线程都有一个私有的本地内存
解决共享对象可见性这个问题: volatile 关键字
3、它如何去学习?
JMM :抽象的概念、理论
JMM对八种操作规则和对volatile的一些特殊规则
就能确定哪里操作是线程安全的`,哪些操作时线程不安全的了。
面试题:
内存交互操作–8种