JVM探究
发布日期:2021-05-07 00:40:09 浏览次数:19 分类:精选文章

本文共 2330 字,大约阅读时间需要 7 分钟。

JVM探究

  • 谈谈你对JVM的理解?java8虚拟机和之前有哪些变化

  • 什么是OOM,什么是栈溢出StackOverflowError? 怎么分析

  • JVM的常用调优参数有哪些?

    百分之九十九都在调堆,部分方法区

  • 内存快照如何抓取,怎么分析Dump文件?知道吗?

  • 谈谈JVM中,类加载器你的认识 ? rt-jar ext application

  1. JVM的位置,在系统中的位置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-crb6wxPP-1615135723570)(C:\Users\ThundeRobot\AppData\Roaming\Typora\typora-user-images\image-20210307010900141.png)]

  2. JVM的体系结构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DPvpXT1Z-1615135723571)(C:\Users\ThundeRobot\AppData\Roaming\Typora\typora-user-images\image-20210307011556198.png)]

  3. 类加载器

    作用:加载class文件

    • 虚拟机自带的加载器
    • 引导类加载器
    • 扩展类加载器 ExtClassLoader
    • 应用程序加载器 AppClassLoader
  4. 双亲委派机制

  5. 沙箱安全机制

  6. Native

  7. PC寄存器

  8. 方法区

三种JVM

  • sun 公司 HotSpot

  • JRockit Ocacle 世界上最块的jvm

  • J9VM IBM

我们学习的都是HotSpot

Heap, 一个JVM只有一个堆内存,堆内存的大小是可以调节的

类加载读取文件后,一般把什么东西放在堆中? 类的实例

里面分三个区域

新生区

老年区

永久区

堆内存错误 OOM ,堆内存满了 OutOfMemoryError

JDK8以后,永久存储区改了一个名字 ----- 元空间

新生区

类诞生、成长、甚至死亡的地方

EdenSpace 所有对象都在这new

幸存者区(0、1)

EdenSpace 满了,轻GC,存活进入幸存者区

幸存区满了,重GC

存活进入养老区

经研究:99%的对象都是临时对象

永久区:

这个区域常驻内存中。用来存放JDK自身携带的Class对象,包括一些Interface元数据,存储的是java运行时的一些环境或类信息~,这个区域不存在垃圾回收!!

关闭虚拟机就会释放这个内存

如果一个启动类,加载了大量的第三方jar包。Tomcat部署了太多的应用,或者大量动态生成的反射类。不断的被加载到内存慢,就会出现OOM。

  • jdk1.6之前:永久代,常量池在方法区中
  • jdk1.7 : 永久代存在,但是慢慢退化,去永久代,常量池在堆中
  • jdk1.8之后:无永久代,常量池在院空间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ax4IoFrh-1615135723573)(C:\Users\ThundeRobot\AppData\Roaming\Typora\typora-user-images\image-20210307125325134.png)]

元空间,逻辑上存在,但是物理上不存在

在一个项目中,突然出现OOM故障,如何排除?

  • 能够看到第几行代码出错:内存快照工具, MAT, Jprofiler
  • Debug,一行行分析代码

MAT,Jprofiler作用:

  • 分析Dump内存文件,快速定位内存泄漏
  • 获取堆中的数据
  • 获得大的对象
  • 。。。。
  1. 新生区、老年区
  2. 永久区
  3. 堆内存调优
  4. GC垃圾回收 常用算法 复制 标记

JVM在进行GC时,并不是对这三个区域同一回收。大部分回收都是回收新生代

  • 新生区
  • 幸存区
  • 老年区

GC两个种类:轻GC(普通的GC) 重GC(全局GC)

题目:

  • JVM的内存模型和分区 详细到每个区放什么

  • 堆里面由哪些分区? Eden,from,to 老年区,说说他们的特点

  • GC的算法有哪些?标记清除法 标记整理法 复制算法 引用计数器,怎么用

  • 普通GC和重GC分别在什么时候发生

  • 当一个对象经历15次GC,还没有死,就会进入老年区

    -XX:MaxTenuringThreashold=999这个参数可以设定进入老年代的时间

复制算法:

  • 好处:没有内存的碎片
  • 坏处:浪费内存空间~,多了一半空间永远空着(to),假设对象100%存活(极端情况),复制算法成本很高
  • 最佳使用场景:对象存活度较低的时候;所以在新生区使用复制算法
  1. JMM
  2. 总结

标记清除算法

  1. 扫描对象,对或者的对象进行标记
  2. 清除:对没有标记的对象进行清楚
  3. 弊端:内存碎片化,两次扫描严重浪费时间,标记也占空间
  4. 优点:不需要额外的空间

标记清除压缩算法:

  1. 压缩,防止内存碎片化,再次扫描,向一段移动存活的对象
  2. 多了一个移动成本

再优化

先标记清除五次,最后再进行压缩,压缩次数少一些

总结

内存效率:复制算法>标记清除>标记压缩算法(时间复杂度)

内存整齐度:复制算法=标记压缩算法 > 标记清除

内存利用率:标记清除算法 = 标记压缩算法 > 复制算法

没有最优的算法吗?

没有,没有最好的算法,只有最合适的算法

  • GC: 分代收集算法

年轻代:

  • 存活率低 复制算法!

老年代:

  • 区域大:存活率高 标记清除(内存碎片不是太多,多几次再压缩)+ 标记压缩 混合实现
  • JVM调优 标记清除几次之后再压缩
  1. 百度 思维导图
  • 每次GC,都会将Eden活的对象移到幸存区

  • 一旦Eden区被GC后,就空

  • 当对象从伊甸园区活下来,会进入幸存区

上一篇:MySQL B+树
下一篇:java 类加载器的双亲委派机制

发表评论

最新留言

很好
[***.229.124.182]2025年03月22日 08时59分08秒