初探JVM
JVM探究
- 请你谈谈你对JVM的理解?java8虚拟机和之前的变化与更新
- 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
- JVM的常用调优参数有哪些
- 内存快照如何抓取,怎么分析Dump文件?可以利用jprofiler这个插件
- 谈谈JVM中,类加载器你的认识
1、JVM的位置
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-91DipQ5z-1615108712272)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-1.png)]](https://i-blog.csdnimg.cn/blog_migrate/92e5518e3b565c29021a0ad4e7b7fa39.png)
2、JVM的体系结构
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fKQ5D2V9-1615108712276)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-2.png)]](https://i-blog.csdnimg.cn/blog_migrate/3e4bbd83318dd9c52ce8d95607b708de.png)
3、类加载器
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kiwYdnsx-1615108712278)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-3.png)]](https://i-blog.csdnimg.cn/blog_migrate/f57871b4d83fd8cbbb0fff58ff546c1e.png)
4、双亲委派机制
首先你要了解JVM中提供了三层ClassLoader
- BootstrapClassLoader:主要负责加载和心类库(例如:java.lang.等)
- ExtClassLoader:主要是负责加载jre/lib/ext目录下的一些扩展jar
- APPClassLoader:主要是负责加载应用程序的主函数类
概念:当一个类收到类加载请求,它首先不会尝试自己去加载,而是把这个请求委派给父类完成,每一层次类加载器都是如此,一次所有的加载请求都应该传送到启动类加载中,只有当父类加载器反馈自己无法完成这个请求的时候,子类加载器才会自己尝试加载
优势:这样可以防止核心库别随意篡改;避免重复加载。
5、沙箱安全机制、Native、PC寄存器、方法区、栈、三种JVM
5、方法区与元空间的解释与区别
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X60G1Rax-1615108712279)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1.3.png)]](https://i-blog.csdnimg.cn/blog_migrate/9dadb3bd2ed2eb052c4c0b689eee798e.png)
11、堆,新生去、老年区、永久区,堆内调优
6、GC
1、常用算法:标记清除法、标记压缩、复制算法、引用计数器
6.1、复制算法:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ChdiLGRT-1615108712280)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-4.png)]](https://i-blog.csdnimg.cn/blog_migrate/97a7cf32551aa82c2a8c99ed5be554fc.png)

-
好处:没有内存碎片
-
坏处:浪费了内存空间;多了一般空间永远是空的To,假设对象100%存活(极端情况)
复制算法最佳使用场景:对象存活度比较低:新生区~
6.2、标记压缩:
对标记清除法的优化
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BaQLWPfD-1615108712283)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-5.png)]](https://i-blog.csdnimg.cn/blog_migrate/4fab03f2c4b4cb858195454af7161c6d.png)
-
优点:不需要额外的内存空间
-
缺点:两次扫描和一次压缩,比较耗时
-
解决了:标记清除法的内存碎片化
6.3、总结
- 内存效率:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)
- 内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法
- 内存利用率:标记压缩算法 = 标记清除算法 > 复制算法
没有最优的算法只有最合适的算法------->GC分代收集算法
年轻代
- 存活率低
- 复制算法
老年代:
- 区域大:存活率
- 标记清除(内存碎片不太多)+标记压缩混合实现
7、JMM
1、什么是JMM?
JMM是 Java Memory Model
2、它是干啥的?
作用:缓存一致协议,用于定义数据读写的规则
JMM定义了线程工作内存之间的抽象关系:线程之间的共享变量存储在主内存中,每一个线程都有一个私有的本地内存。
解决共享对象可见性这个问题:可以用 volatile 关键字和synchronized同步机制
8代码和IDEA虚拟机参数配置
8.1、这是IDEA的java虚拟机参数配置的地方
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DVMVVOD5-1615108712284)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-6.png)]](https://i-blog.csdnimg.cn/blog_migrate/a3a441388ebe2921fa29ef767f24a2e8.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c50kAdlq-1615108712286)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-7.png)]](https://i-blog.csdnimg.cn/blog_migrate/22f8e29ade72c2fd194006204df19ead.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hS1uwrZc-1615108712288)(C:\Users\10404\Desktop\寒假java学习\JVM图片\1-8.png)]](https://i-blog.csdnimg.cn/blog_migrate/60257a6500d64cfbff26f49a001f2fd0.png)
8.2、代码
package 寒假训练.狂神.JVm;
public class Demon2 {
public static void main(String[] args) {
//返回虚拟机试图使用的最大内存
long max = Runtime.getRuntime().maxMemory();
//返回jvm的初始化的总内存
long total = Runtime.getRuntime().totalMemory();
System.out.println("max="+max+"字节\t"+(max/(double)1024/1024)+"MB");
System.out.println("total="+total+"字节\t"+(total/(double)1024/1024)+"MB");
//默认情况下:分配的总内存 是电脑内存的1/4,而初始化的内存:1/64
//OOM:内存溢出
/**
* 解决方法:1、尝试扩大堆的内存空间,其实就是调JVM的参数。
* 格式:-Xms1024m -Xmx1024m -XX:+PrintGCDetails
*两个1024可以替换成自己想要替换的数字
* 2、分析内存,看一下哪个地方出现了问题(专业工具jprofiler)
*/
}
}
OOM的代码
package 寒假训练.狂神.JVm;
import java.util.ArrayList;
//-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
public class Demon3 {
public static void main(String[] args) {
byte[] array = new byte[1*1024*1024];
ArrayList<Demon3> list = new ArrayList<>();
int count = 0;
try {
while (true){
list.add(new Demon3());
count=count+1;
}
} catch (Error error){
System.out.println(error.getMessage());
}
}
}
217





