一篇文章教你了解JVM-狂神JVM学习笔记

以下是我JVM学习的笔记,适合用于基本了解JVM

 

请你谈谈你对JVM的理解?

java8虚拟机和之前的变化更新

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

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

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

谈谈JVM中,类加载器你的认识?

 

1、JVM的位置  2、JVM的体系结构

 

3、类加载器

作用:加载class

  1. 虚拟机自带加载器
  2. 启动类(根)加载器  BOOT
  3. 扩展类加载器  EXC
  4. 应用程序加载器  APP

 

4、双亲委派机制:为了安全  APP --> EXC --->BOOT

1、防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
2、保证核心.class不能被篡改。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

 

5、沙箱安全机制

6、Native

1、native:用native关键字。说明java的作用范围打不到了,回去调 用底层C语言库 

2、JNI的作用:扩展java的使用,融合不同的编程语言为java所用: 最初C,C++java诞生时c、c++横行,要立足就要调用c、c++

3、JNI在内存区域中专门开辟了一块标记区域:本地方法栈 Native Method Stack,登记了native方法。

4、执行的时候native方法会本地方法栈,调用本地方法接口 (JNI java native interface)通过JNI 加载本地方法库中的方法。

5、在企业级应用中较为少见,通过java驱动打印机、robot等情况下 使用,掌握即可。

7、PC寄存器

程序计数器:Program Counter Register

每个线程都有一个程序计数器,是线程私有的,储存即将执行的 指令代码的地址,占用内存空间非常小,(用来计数使线程有序等, 比如线程1 线程2 线程...)

8、方法区(共享区间)

1、静态变量、常量、类信息(构造方法、接口定义)、运行时常量池 都 存在方法区中

2、实例化时 实例和实例变量赋值存在堆内存中

3、栈中存放实例的引用,方法执行时入栈,方法执行完弹栈

4、方法区和堆 有垃圾回收,栈中没有

 

9、栈

队列:管形、先进先出(FIFO first input first output)

栈:存放8大基本类型,对象的引用,实例的方法

桶形:先进后出

main()方法先执行,最后执行结束

栈内存 主管程序运行,生命周期和线程同步

线程结束,栈内存也就是释放了。栈不存在垃圾回收

栈帧:栈顶、栈底(程序正在执行的方法一定在栈的顶部)

每个栈帧中有:方法的索引、入参出参、本地变量、Class File、父帧、子帧

 

10、对象的初始化

父类的静态代码块

->子类的静态代码块

->初始化父类的属性值/父类的普通代码块(自上而下的顺序排列)

->父类的构造方法

->初始化子类的属性值/子类的普通代码块(自上而下的顺序排列)

->子类的构造方法。

注:构造函数最后执行。

 

11、三种JVM

Sun公司 HotSpot(一般用)

BEA公司JRockit

IBM公司J9 VM

 

12、 Heap

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

类加载器读取了类文件后,一般把什么放入堆中?类、方法、常量、变量、所有引用类型的真实对象

 

13、新生区Eden Space) 轻量级GC(轻GC)

新生区:伊甸园区、幸存区012345...  

N次(定义上限)垃圾回收之后,进入养老区

 

14、老年区:重量级GC(Full GC)

GC,主要在伊甸园区和养老区。

内存满了,报OutOfMemory堆内存错误。

99%的对象都是临时对象,进不到养老区。

 

15永久区JDK8之后叫 元空间

不存在GC,关闭VM虚拟机就会释放这个区域的内存。

这个区域是常驻内存的。用来存放JDK自身携带的Class对象。Interface元数据,存的是java运行时的一些环境或类信息。

一个启动类加载了大量的第三方jar包、Tomcat部署了太多应用大量动态生成反射类。不断加载直到内存满了,就会报OOM。

Jdk6前:永久代,常量池在方法区中

Jdk7:永久代,常量池在堆中

Jdk8后:无永久代,常量池在元空间

1.8时的堆:方法区中包含一小块常量池

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

16堆内存调优

1、OOM的处理 :设置内存 -Xms4096m -Xmx256m -XX:+PrintGCDetails

1、尝试扩大堆内存,看结果

2、分析内存,看一下哪个地方除了问题(用专业工具)

2、在项目中突然出现OOM故障,如何排除:

1、Dubug一行行分析:不现实

2、通过插件直接看到第几行出错:内存快照分析工具:MAT、Jprofiler

3、MAT,Jprofiler的作用:

1、分析Dump内存文件,快读定位内存泄漏

2、获得堆中的数据

3、获得大的对象

等等

//设置内存 -Xms4096m -Xmx256m -XX:+PrintGCDetails  (打印GC信息到控制窗口)

//堆Dump  -Xms4096m -Xmx256m -XX:+HeapDumpOnOutOfMemoryError  (on后面是条件)

 

17、GC常用算法:标记清除法、标记压缩、复制算法、引用计数器法

1、引用计数法:一般不用引用计数法,给每个对象分派程序计数器,计数为0的回收

 

2、复制算法:每次GC,都会将Eden区中活着的对象移到幸存区中幸存区,幸存区放不下就放到养老区了。Eden区被GC后就是空的。幸存区谁空谁是to,非空from

复制算法的缺点:浪费一半空间(to得是空的),从from幸存区复制到to幸存区,如果对象 都存活,太浪费资源。因此当对象存活率低才会用复制算法

 

3、标记清除:回收时对活着得对象扫描进行标记,对没标记得对象扫描进行清除

缺点:两次扫描,严重浪费时间,会产生内存碎片

优点:对比复制算法 不需要额外的内存空间(空的To幸存区)

 

4、标记压缩:在标记清除得基础上,再次扫描,向一端移动存活得对象,防止内存碎片产生。又多了一个移动的成本

5、最好进行多次标记清除,然后进行一次标记压缩,降低成本

 

17、总结

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

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

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

 

GC是分代收集算法:

年轻代:存活率低 用 复制算法

老年代:区域大,存活率高 用 标记清除+压缩混合

 

JVM学会之后想深入研究可看《深入学习JVM》

也可研究新的模型:JMM

Java Memory Model

什么是JMM ? 百度百科

干嘛的? 官方、博客、对应视频

如何学习?看 + 面试题

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShyTan

喜欢的给点打赏呗,纯手打

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值