JVM 探究
JVM 探究
-
请你探探你对jvm的理解?java8虚拟机和之前的变化更新?
-
什么是OOM,什么是栈溢出StackOverFlowError?怎么分析
-
JVM的常用调优参数有哪些
-
内存快照如何抓取,怎么分析Dump文件?知道吗?
-
读读JVM中,类加载器你的认识?
1.jvm的位置
在操作系统之上
2.jvm的体系结构
3.类加载器
作用:加载Class文件 ~ new Student();
1 .虚拟机自带的加载器
-
启动类(根)加载器
-
扩展类加载器
-
应用程序加载器
4.双亲委派机制
package lang; import javax.sound.midi.Soundbank; import java.sql.SQLOutput; public class String { //双亲委派机制,安全 //1.APP--->EXC---BOOT(最终执行) //BOOT //EXC //APP public Stirng toString(){ return "hello"; } public static void main(String[] args) { String s =new String(); System.out.println(s.getClass().getClassLoader()); s.toString(); } /** * 1. 类加载器收到类加载的请求 * 2. 将这个请求向上委托给父亲加载器去完成,一直向上委托,知道启动类加载器 * 3. 启动加载器检查是否能够加载当前这个类,额能加载就结束。 * */ }
5.沙箱安全机制
6.Native
7.PC寄存器
8.方法区: static,final,Class,常量池
9.栈
10.三种jvm
11.堆
真相:经过研究,99%的对象都是临时对象!
12.新生区、老年区
- 新生区
- 类:诞生和成长的地方,甚至死亡;
- 伊甸园,所有的对象都是在伊甸园区new出来的!
13、永久区
这个区域常驻内存的。用来存放JDK自带携带的Class对象。Interface元数据,存储的是java运行时的一些环境或类信息~
一个启动类,加载了大量的第三方jar包。Tomcat部署了太多的应用,大量动态生产的反射类。不断的被加载。直到内存满,就会出现OOM
- jdk1.6 之前:永久代,常量池在方法区:
- jdk 1.7:永久代,但是慢慢的退化了,去永久代,常量池在堆中
- jdk 1.8之后:无永久代,常量池在元空间
14堆内存调优
package hao; public class Demo2 { public static void main(String[] args) { //返回虚拟机视图使用的最大内存 long max =Runtime.getRuntime().maxMemory(); //字节 1024*1024 //返回jvm的初始化总内存 long total =Runtime.getRuntime().totalMemory(); System.out.println("max="+max+"字节\t"+(max/(double)1024/1024)+"MB"); System.out.println("total="+max+"字节\t"+(total/(double)1024/1024)+"MB"); // 默认情况下: 分配的总内存 是电脑内存的1/4,而初始化的内存:1/64 } //OOM: //1.尝试扩大内存看结果 //2.分析内存,看一下那个地方出现了问题(专业工具) // -Xms1024m -Xmx1024m -XX:+PrintGCDetails // 305664K +699392K =1005056 K =981.5M }
"C:\Program Files\Java\jdk1.8.0_251\bin\java.exe" -Xms1024m -Xmx1024m -XX:+PrintGCDetails "-javaagent:D:\app\appInstall\IntelliJ IDEA 2020.1.1\lib\idea_rt.jar=3763:D:\app\appInstall\IntelliJ IDEA 2020.1.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_251\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_251\jre\lib\rt.jar;D:\workspace\java\网络编程\target\classes" hao.Demo2 max=1029177344字节 981.5MB total=1029177344字节 981.5MB Heap PSYoungGen total 305664K, used 20971K [0x00000000eab00000, 0x0000000100000000, 0x0000000100000000) eden space 262144K, 8% used [0x00000000eab00000,0x00000000ebf7afb8,0x00000000fab00000) from space 43520K, 0% used [0x00000000fd580000,0x00000000fd580000,0x0000000100000000) to space 43520K, 0% used [0x00000000fab00000,0x00000000fab00000,0x00000000fd580000) ParOldGen total 699392K, used 0K [0x00000000c0000000, 0x00000000eab00000, 0x00000000eab00000) object space 699392K, 0% used [0x00000000c0000000,0x00000000c0000000,0x00000000eab00000) Metaspace used 3229K, capacity 4496K, committed 4864K, reserved 1056768K class space used 347K, capacity 388K, committed 512K, reserved 1048576K
15 GC 垃圾回收,主要是在伊甸园区和养老区~
假设内存满了,OOM,堆内存不够!
1.常用算法
在一个项目中,突然出现了OOM故障,那么该如何排除~ 研究为什么出错~
- 能够看到代码第几行出错:内存快照分析工具,MAT,Jprofiler
- Dubug,一行行分析代码!
MAT,Jprofiler作用
-
分析Dump内存文件,快速定位内存泄漏;
-
获得堆中的数据
-
获得大的对象
-
。。。
-
总结
JVM 在进行GC时,并不是对这三个区域统一回收。大部分时候,回收都是新生代~
-
新生代
-
幸存区 (form, to)
-
老年区
-
年轻代:
- 存活率低
- 复制算法!
老年代:
- 区域大:存活率
- 标记清除(内存碎片不是太多)+标记压缩混合实现
GC 两种类:轻GC (普通的GC),重GC(全局GC)
GC题目:
- JVM的内存模型和分区 -详细到每个区放什么?
- 堆里面的分区有哪些?Eden,form,to,老年区,说说他们的特点!
- GC的算法有哪些?标记清除法,标记压缩,复制算法,引用计数器,怎么用的?
- 轻GC和重GC分别在什么时候发生?
引用计数法:
复制算法
标记清除算法
- 优点:不需要额外的空间!
- 缺点:两次扫描,严重浪费时间,会产生内存碎片。
标记压缩
再优化
总结
内存效率:复制算法>标记清除算法》标记压缩算法(时间复杂度)
内存整齐度:复制算法 =标记压缩算法》标记清除算法
内存利用率:标记压缩算法 =标记清除算法》复制算法
思考一个问题:难道没有最优算法吗?
答案:没有,没有最好的算法,只有最适合的算法 -----》GC:分代收集算法
JMM
1.什么是JMM?
JMM