JVM的探究笔记

面试问题

  • 请您谈谈你对jvm的理解?
  • Java8虚拟机和之前的更新变化?
  • 什么是OOM ,什么是栈溢出?
  • JVM的调优参数有哪些?
  • 内存快照如何抓取,怎么分析Dump文件?
  • 谈谈JVM中,类加载器的认识?

JVM的理解

JVM的位置

在这里插入图片描述

JVM的体系结构

在这里插入图片描述

类加载器

作用:加载class文件
在这里插入图片描述
类加载器的类型

  • 应用程序加载器
  • 扩展加载器
  • 根加载器 Java程序无法调用,会输出null值
    在这里插入图片描述
    不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理也会先检查自己是否已经加载过,如果没有再往上。注意这个类似递归的过程,直到到达Bootstrap classLoader之前,都是在检查是否加载过,并不会选择自己去加载。直到BootstrapClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。
    在这里插入图片描述

native关键字

带有native关键字的,说明Java的调用范围达不到,要去底层调用C语言的代码。
进入本地方法,调用本地方法的接口(JNI)。
JNI的作用:融合不同的语言进入Java中去。

为什么要又native关键字

  • Java诞生的时候,c和c++比较流行,Java要想活下去,必须拥有调用c和c++的方法
  • 它在内存程序中开辟了本地方发栈,登记native方法,最终驱动程序的时候,加载本地方法库中的方法去调用JNI。

PC寄存器

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区的方法字节码。在程序中占用非常小的内存,几乎可以忽略不计。

方法区

方法区被所有线程所共享的,构造函数和接口代码等也在此定义。一般放置以下东西

  • 静态常量
  • 常量
  • 类信息(接口定义,构造方法)
  • 运行时的常量池

栈:栈内存,主程序的运行,生命周期和线程同步。
线程结束,占内存也是释放,对于栈来说,不存在垃圾回收的问题。
一旦线程结束。栈就over。
栈里面存的数据:8大基本类型+对象引用+实例方法。
栈满了:StackOverFlowError

栈+堆+方法区:交互关系

JVM种类

  • hotspot
  • BEA
  • IBM

一个jvm只有一个堆,堆内存的大小是可以调节的。
类加载器读取类文件后,类,方法,常量,变量这些,而已大部分保存我们的引用类型的真是对象。
堆的分类:

  • 新生区(伊甸园区)
    1. 类的诞生,成长,甚至死亡的区域
  • 养老区
  • 永久区(元空间)-------------方法区在这个区域------方法区里面有常量池
    (逻辑上存在物理上不存在)原因:堆内存=新生区+养老区就满了。
  1. 这个区域是常驻内存。用来存放Java自身携带的class对象。存储的为Java运行时的一些环境或者类信息。这个区域不存在垃圾回收。关闭JVM时会释放这个区域的内存。
  2. 当大量的第三方jar被加载时,或者当tomcat部署太多应用,大量的反射类,不断的被加载。直到内存满了,就会出现OOM;
  3. 当出现OOM时怎么解决
    1. 尝试扩大内存。用Xms和Xmx调节堆内存大小
    2. 分析内存。查找问题

GC垃圾回收,主要在新生区和老年区。
OOM 堆内存不够 OutOfMemoryError;Java heap space
在这里插入图片描述
在这里插入图片描述

堆内存调优

在一个项目中,突然出现了OOM故障,那么该如何排除 研究为什么出错~

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

MAT, Jprofiler作用

  • 分析Dump内存文件,快速定位内存泄露;
  • 获得堆中的数据
  • 获得大的对象~

MAT是eclipse集成使用 在这里不学

Jprofile使用

1.在idea中下载jprofile插件 2.联网下载jprofile客户端 3.在idea中VM参数中写参数 -Xms1m -Xmx8m -XX: +HeapDumpOnOutOfMemoryError 4.运行程序后在jprofile客户端中打开找到错误 告诉哪个位置报错 命令参数详解 // -Xms设置初始化内存分配大小/164 // -Xmx设置最大分配内存,默以1/4 // -XX: +PrintGCDetails // 打印GC垃圾回收信息 // -XX: +HeapDumpOnOutOfMemoryError //oom DUMP

GC

在这里插入图片描述
JVM在进行GC时,并不是对这三个区域统一回收。
大部分时候,回收都是新生代-- 新生代 ,幸存区(form,to)
老年区 GC两种类:轻GC (普通的GC), 重GC (全局GC)

堆里面的分区有哪些?

Eden, form, to, 老年区

GC的算法有哪些?

标记清除法
标记压缩清除算法
复制算法
引用计数器

轻GC和重GC分别在什么时候发生?

轻GC一般发生在新生区。一般用到的算法是复制算法。
重GC一般作用于老年区,一般用标记清除算法和标记压缩算法混合使用。

引用计数器:

在这里插入图片描述
引用计数法 很少使用了

##复制算法
在这里插入图片描述
每次将伊甸园区和一个幸存区的对象复制到另外一个幸存区,然后清空伊甸园区和一个幸存区。
好处:没有内存的碎片~
坏处:浪费了内存空间~ :多了一半空间永远是空to。假设对象100%存活(极端情况) 复制算法最佳使用。
在这里插入图片描述

标记清除算法

在这里插入图片描述
将幸存的对象标记,然后清除不被标记的对象。
优点:不会占用额外的空间。
缺点:将会进行两次扫描,占用时间长。

标记压缩算法

在这里插入图片描述
将幸存的对象标记,然后清除不被标记的对象。再将对象压缩在一个空间里面。

总结

三大gc算法比较(不含程序计数算法)

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

没有最好的算法,只有合适的算法--------GC分代收集算法

年轻代:
存活率低------复制算法
老年代:
存活率大-----标记清除几次+标记压缩

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值