0
点赞
收藏
分享

微信扫一扫

JVM快速入门

small_Sun 2022-04-02 阅读 32
java

JVM入门

JVM探究

面试题:

  • 请你谈谈你对JVM的理解?Java8虚拟机的更新
  • 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
  • JVM常用调优参数有哪些?
  • 内存快照如何抓取?怎么分析Dump文件?
  • 谈谈JVM中,类加载器你的认识?
    解答见本文最后 17.总结

1. JVM的位置

在这里插入图片描述

2. JVM体系结构

栈和计数器中不会存在垃圾,只有方法区和堆中存在,因此调优主要是针对堆。
在这里插入图片描述

3. 类加载器

作用:加载class文件

分类:
1.虚拟机自带的加载器
2.启动类加载器(根加载器)
3.扩展类加载器 — jre/lib/ext文件中
4.应用程序加载器(系统类加载器)— jre/lib/rt.jar

流程:
1.类加载器收到类加载的请求
2.将这个请求向上委托父类加载器去完成,一直向上委托,直到启动类加载器
3.启动类加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子类加载器进行加载
4.重复步骤3
Class Not Found ~

4. 双亲委派机制

目的:保证安全
流程:由 应用程序加载器 到 扩展类加载器 到 根加载器 中找,最终执行根加载器

5. 沙箱安全机制

6. native关键字

凡是带了native关键字的,说明java的作用范围达不到了,会去调用底层的C语言库!
过程:会进入本地方法栈,本地方法栈会调用本能地方法接口JNI,JNI的作用是扩展Java的使用融合不同的编程语言为Java所用
Java诞生的时候C和C++横行,为了调用其在内存中专门开辟了一块标记区域:Native Method Stack本地方法栈,登记native方法,最终执行的时候加载本地方法通过JNI

现在常用的调用其他语言接口的方法:Socket,WebService,http~

7. PC寄存器

程序计数器:Program Counter Register
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的字节码(用来存储指向下一条指令的地址,也即要执行的指令代码)在指令引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计

8. 方法区

方法区:Method Area
方法区是被所有的线程共享的,所有的字段和字节码信息,以及一些特殊方法如构造函数,接口代码也在此定义,简单的说,所有定义的方法的信息都保存在该区域,此区域属于共享空间
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在于堆内存中,和方法区无关即static,final,Class,常量池

9. 栈

栈内存,主管程序运行。生命周期和线程同步
线程结束,栈内存也就释放了,对于栈来说不存在垃圾回收问题
一旦线程结束,栈就over了!

栈包含:8大基本类型 + 对象引用 + 实例的方法
栈运行原理:栈帧
栈满了:StackOverflowError

栈 堆 方法区 的交互关系

10. 三种JVM

  • Sun公司 HotSpot
  • BEA公司JRockit
  • IBM公司Oracle-J9VM

11. 堆

堆:Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的
类加载器读取了类文件之后,一般会把什么东西放到堆中?–引用类型的真实对象
堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用

堆中内存可以细分为三个区域:

  • 新生区
  • 养老区
  • 永久区
    在这里插入图片描述
    GC垃圾回收主要是在伊甸园区和养老区
    假设内存满了,OutOfMemoryError,堆内存不够!
    JDK8以后,永久存储区改了一个名字,元空间

12. 新生区、老年区

新生区:类 诞生和成长的地方,甚至死亡;
新生区又分为:伊甸园区和幸存者区(0区,1区)
所有的对象都是在伊甸园区new出来的

老年区:

13. 永久区

这个区域是常驻内存的。用来存放JDK自身携带的Class对象,Interface元数据,存储的是java运行时的一些环境或类信息这个区域不存在垃圾回收
JDK1.6之前:永久代,常量池在方法区
JDK1.7 :永久代,但慢慢退化了,去永久代,常量池在堆中
JDK1.8之后:无永久代,常量池在元空间

在这里插入图片描述
在这里插入图片描述
元空间逻辑上存在,物理上不存在

14. 堆内存调优

OOM如何解决
1.尝试扩大堆内存看结果
2.分析内存,看一下哪个地方出了问题(专业工具)
最直接也是最慢的是 一行一行分析代码
专业内存快照分析工具MAT,Jprofiler能看到代码第几行出错

MAT,Jprofiler的作用:
1.分析Dump内存文件,快速定位内存泄漏
2.获得堆中数据
3.获得大的对象

命令:
-Xms1m -Xmx8m -XX:PrintGCDetails
-Xms8m -Xmx16m -XX:HeapDumpOnOutOfMemoryError
其中:
-Xms 设置初始化内存大小 默认约为总内存1/64
-Xmx 设置最大分配内存大小 默认约为总内存1/4
-XX:PrintGCDetails 打印GC垃圾回收信息
-XX:HeapDumpOnOutOfMemoryError OOM Dump

15. GC:垃圾回收机制

垃圾回收只存在于堆和方法区中

JVM在进行GC时,并不是对三个区域统一回收,99%都在新生代

  • 新生区
  • 幸存区(from to)
  • 老年区
    GC分两类:轻GC,重GC

15.1 常用算法

标记清除法,标记压缩法,复制算法,引用计数法
引用计数法
对每一个对象引用次数进行标记
在这里插入图片描述

复制算法
幸存区谁空谁是to
在这里插入图片描述

好处:没有内存碎片
坏处:浪费了内存空间:多了一半空间永远是空to。假设对象100%存活(极端情况)
复制算法最佳使用场景:对象存活度较低的时候,即在新生区中

标记清除法
在这里插入图片描述
优点:不需要额外空间
缺点:两次扫描严重浪费时间,会产生内存碎片

标记压缩法
对标记清除法优化,防止内存碎片
在这里插入图片描述
总结:
内存效率:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)
内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法
内存利用率:标记压缩算法 > 标记清除算法 > 复制算法

最合适的算法
年轻代:存活率低,使用复制算法
老年代:存活率高,使用标记清除+标记压缩混合实现

16. JMM

17. 总结

常见的关于JVM的面试题

参考:
【狂神说Java】JUC并发编程最新版通俗易懂
Java8新特性之虚拟机的改变
JVM
StackOverFlowError(栈溢出)
OOM分析
jvm之java类加载机制和类加载器(ClassLoader)的详解
新生代 怎么转移到老年代
JVM内存垃圾回收方法
高频八股:new 一个对象在堆中的历程
Java基础篇 - 强引用、弱引用、软引用和虚引用
java对象的强引用,软引用,弱引用和虚引用

举报

相关推荐

0 条评论