JVM核心考案2 | 系统性学习 | 无知的我费曼笔记(图文排版无水印)

无知的我正在复盘JVM。。。
笔记特点是

  • 重新整理了涉及资料的一些语言描述、排版而使用了自己更容易理解的描述。。
  • 提升了总结归纳性
  • 同样是回答了一些常见关键问题。。

JVM-是什么

JVM在总体上的分类

  1. JVM规范 打开Oracle官网文档可以查看
  2. JVM实现 最常用的是Oracle公司使用的Hotspot虚拟机

JVM与JDK的区别

  1. JRE = JVM +Java标准库
  2. JDK = JRE + 开发调试诊断工具

JVM-跨平台跨语言

跨平台

借助JVM,类可以在多个操作系统上运行 且 效果一致。

跨语言

JVM只识别Class文件,与语言是解耦的。比如说Groovy、kotlin、Scala等语言都是编译成字节码,JVM都可以识别他们,从而在JVM上运行。//一定程度上奠定了Java语言强大的生态圈

JVM-运行时数据区

image-20220424154523634

JVM-堆空间

堆内存分为

新生代和老年代

其中新生代又分为Eden(80%)、S0、S1

堆空间运行机制

新生代采用复制算法;老年代采用其他算法

为什么新生代又要划分

这是为了提高空间利用率,解决原本空间利用率只有50%的问题

当新创建对象时,其会被放在Eden

当Eden满了时,发生第一次垃圾回收、将对象复制到S0

当发生下一次垃圾回收时,如果Eden又满了,复制到S1,同时把上一次在S0的也复制S1

  • 如果S1满了、且垃圾回收发生了15次以上,复制到到老年代

//结果是 每次仅仅浪费10%的空间

//为什么能这样做? 这是因为对象很快就会变成垃圾,那么Eden可以划分很大的空间

image-20220424154946105

JVM-内存溢出示例

image-20220424160810731

JVM-内存泄露

是什么

当无用的对象继续占用内存时,这些不使用的内存,没有被释放

典型场景是 当每一个请求或者每一次操作处理时,都为其分配了内存,却有一部分不能回收,随着处理的请求越来越来多,内存泄露就越来越严重。

与内存溢出的关系

不被处理的内存泄露会随着时间推移造成内存溢出

内存溢出是 资源管理、程序BUG导致的

内存泄露是 内存不足和内存溢出导致的

JVM-对象头

是什么

image-20220418145024608

  • 类型指针是 对象指向自身元类型的指针。//作用是 虚拟机通过这个指针,确定这个对象是哪个类的实例

分析对象内存的占用

image-20220418145459042

JVM-常用JVM启动参数

JVM-设置堆空间的最大值要考虑的

推荐配置系统或容器的可用内存的 70%~80%最好。

之后,还要考虑到系统自己的内存、其他空间的内存来调整

JVM-排查OOM的手段

查看控制台异常信息

VisualVM查看导出异常文件

这需要设置“VM options”参数。可查看原因、异常位置

//机制是,当该异常出现时,会自动导出异常文件到项目的根目录下

//ViusalVM在安装了hotsopt的JDK(比如JDK1.8)中的根目录

JVM-Java8中默认使用的垃圾收集器

Java8的Hostpot JVM 使用的是并行垃圾收集器(Parallel GC),其包含两个收集器:一是Parallel Scavenge;一是Parallel Old。

其他厂商提供的JDK8也基本上默认使用该垃圾收集器

image-20220423015043827

JVM-并行垃圾收集

是什么

使用多个GC worker 线程并行地执行垃圾收集

好处是

能够充分利用多核CPU的能力,缩短垃圾收集的暂停时间

在应用场景中

除了单线程的GC外,PS、CMS、G1等新型垃圾收集器都是用多线程并行执行CPU操作

image-20220424161214863

  • 当CPU使用的是用户线程、发生垃圾回收时,程序进入安全点而暂停所有用户线程,开启GC线程并行地进行垃圾回收

JVM-安全点

安全点-是什么

JVM在字节码指令中选择的一些不会发生引用变化的指令。//比如方法调用、循环跳转、异常跳转等

安全点-为什么

为了确保用户暂停的这行字节码不会发生引用关系变化

安全点-机制

GC要暂停业务线程,就要主动式中断,而不是抢断

主动式中断是 设置一个中断标志,各个业务线程在运行过程中不断地主动轮询这个标志

  • 如果发现中断标志为true,就会在自己最近的“安全点”上主动挂起

安全区域-是什么

引用关系不会发生变化的某一段代码

安全区域-为什么

这是因为当业务线程处于sleep()、Blocked状态时,那么程序没有办法进入安全点

JVM-排查CPU突然飙升

  1. TOP命令 找到消耗很高的CPU进程的ID(假设2732)
  2. TOP -P 2732 单独监控该进程
  3. 在第二步的监控界面输入H 获取当前进程的所有线程信息
  4. 找到消耗CPU特别高的线程编号PID
  5. 执行JSTACK 2732

JVM-类加载

image-20220424163454212

@加载Loading阶段详解

  1. 转换Class为二进制字节流——通过这个类的全限定名
  2. 转换这个字节流所代表的静态存储区(字符串常量池、方法等等) 为 方法区的运行时数据结构
  3. 生成一个代表这个类的java.lang.Class对象——在内存中。//这个对象作为方法区中这个类的各种数据的访问入口

类加载器是什么

通过这个类的全限定名,来获取该类的二进制字节流的动作

//结果是 让程序自己决定“如何获取所需的类”

JVM-G1收集器的特点

是什么

垃圾优先。就是哪一块垃圾最多,就优先处理它

处理方式

  1. 空间整合
  2. 多线程+并发+可预测停顿
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值