JVM (三) 详细学习jvm

ゞ 浴缸里的玫瑰 2023-07-15 09:04 137阅读 0赞

此文针对B栈Monkey课程所做笔记,个人认为讲的真心不错,https://www.bilibili.com/video/av94156750?p=1

一、什么是JVM

熟悉jvm首先了解java体系,通过查看java代码相关编译运行,更好的了解jvm;从图中可以看出jvm底层是和操作系统打交道的

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70

1、首先编写HelloWorld.java

  1. public class HelloWorld {
  2. // 类的属性:常量、变量、成员属性
  3. private Object object = new Object();
  4. private static int i = 0;
  5. private static String s = "helloworld";
  6. public int add () {
  7. int a = 1;
  8. int b = 2;
  9. int c = (a + b) * 100;
  10. return c;
  11. }
  12. public static void main(String[] args) {
  13. HelloWorld app= new HelloWorld();
  14. int result = app.add();
  15. Thread.sleep(100);
  16. System.out.println(result);
  17. }
  18. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 1

此处windows和linux分别下载对应机器的jvm,通过字节码达到在不同环境运行的目的,实现跨平台

二、JVM 底层原理

jvm 包括三部分,jvm运行时数据区、类加载子系统、执行引擎

此处说明一点,

本地方法栈,可以查看代码的Thread.sleep方法,为调用native方法的相关方法

方法区(元空间):为类的属性定义,对应直接内存,主内存

字节码class文件,需要通过java命令,才能到达类加载子系统;

cpu分配相应的时间调度,才能让执行引擎 根据 程序计数器的行号 执行相应的jvm相关方法

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 2

跟踪helloworld执行过程

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 3

main线程启动过程,需要在虚拟机栈、本地方法栈、程序计数器三部分分配空间

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 4

虚拟机栈针加载顺序

项目加载首先会加载main线程到虚拟机栈,然后加载add方法进入虚拟机栈

局部变量表:存储 int、short 、reference、long等数据类型

首先 执行引擎 根据iconst_1将1压入操作数栈,然后分局istore_1,将1赋值给局部变量表中的局部变量a=1,每次执行会根据程序计数器提供的行数进行执行指令,注意7-9之间有一个100,默认为8,执行乘法操作

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 5

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 6

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 7

通过javap -c HelloWorld.class 反编译字节码文件

通过javap -c HelloWorld.class > helloworld.txt 将相关的反编译代码输出到文件,相关操作可以查看jvm指令集

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 8

add方法将计算结果返回给main方法的局部变量表,局部变量表中的引用存在堆中,相应的类信息存在方法区中,其中类和引用的对应关系为一对多的关系

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 9

内存默认占比:

堆分为新生代(1/3) 和 老年代(2/3)

新生代分为Eden (8/10) 、from(1/10) 、to(1/10)

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 10

为什么要进行性能调优?

主要也就是合理利用本来就不多的内存

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 11

内存回收的过程

步骤一:对象创建后默认放到新生代的Eden 区(詹姆斯高斯林为基督教徒),当Eden区内存占用满后,会调用一次 1minor young gc,并根据gc roots的可达性判断,根据对象是否被引用,决定是否清空Eden区

步骤二:然后标记对象的age = 1,并将Eden区清空,将正在使用的对象放到from 区,当from区满后,会调用第二次 2minor gc,并将age = 2

步骤三:将age = 2 的元素,通过复制算法,挪到to区,并将to改为from区,from改为to区,一直循环;直到第15次minor gc调用,将相关的对象移到老年代,默认不老不死,当老年代占用内存满后,就会提示内存不够,内存溢出OOM,并调用full gc,触发STW(网站停顿),整个系统处于不在运行状态

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 12

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 13

为什么采用分代回收的策略?

减少我们的stw 次数,其实就是减少full gc 次数,达到吞吐量、jvm调优

三、性能调优

demo实战

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 14

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 15

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 16

20200315235158145.png

20200315235214129.png

idea vm options 进行的参数配置

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 17

然后采用cms 垃圾收集算法:并发收集器,一般分为7步

初始化标记,并发标记

20200315235359249.png

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 18

cms回收过程

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 19

cms优点:用户响应

缺点:会出现空间碎片

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1Mjc1MjMz_size_16_color_FFFFFF_t_70 20

老年代垃圾清理:采用标记清理算法,将正在使用的标记压缩到一片区域,剩余的都是连续的可用的内存空间,其他不使用的就进行

发表评论

表情:
评论列表 (有 0 条评论,137人围观)

还没有评论,来说两句吧...

相关阅读