JVM学习笔记 -- 老王

168 阅读6分钟

学习资料:

1. JVM跨平台原理

JVM是操作系统上的一个程序,和QQ、微信是一样的;

不同操作系统上运行上的JVM是不一样的,这才是JVM跨平台的本质!而这些JVM提供的功能都是一样的,都可以执行字节码文件,只要把Java文件编译成字节码文件,那么这份字节码文件就可以在各个平台运行。 image.png

2. 字节码的作用

Java是编译+解释性语言,本地提前编译一下,运行时更快一些;一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。 image.png

同时,不同的编程语言编译成字节码文件,也就可以支持跨平台了: image.png

3. JVM的整体结构

image.png

字符串常量、静态变量数据存放区域: image.png 解释器、JIT编译器的区别: image.png

4. 类加载子系统的作用

类加载子系统会将本地磁盘中的字节码文件加载到方法区的内存空间中。 image.png

Refer:

5. 类加载器的分类

不同的类加载器会从不同的地方加载字节码文件,它负责将Class的字节码形式转换成内存形式的Class对象。 image.png

Refer:

6. 类加载器双亲委派的作用

当用APPClassLoader去加载某一个类时,先委派父类去加载; image.png

类加载器双亲委派的作用:1. 避免类的重复加载; 2. 防止核心API被篡改。

ClassLoader#loadClass的代码:

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 查看是否已经加载过该类,加载过的类会有缓存,是使用native方法实现的
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    // 父类不为空则先让父类加载
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                    // 父类是null就是BootstrapClassLoader,使用启动类类加载器加载
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // 父类类加载器不能加载该类
                }

                // 如果父类未加载该类
                if (c == null) {
                    long t1 = System.nanoTime();
                    // 让当前类加载器加载
                    c = findClass(name);
                }
            }
            return c;
        }
    }

7. Tomcat为什么要自定义类加载器?

对应用A和应用B设置各自单独的类加载器,也就是不同的WebappClassLoader实例,这样两个应用中的Hello.class都能被各自的类加载器所加载,不会冲突。 image.png

8. 运行时数据区域的组成

JVM的整体结构: image.png

运行时数据区: image.png 方法区、堆区是多个线程共享的,而Java方法栈、本地方法栈、程序计数器是单个线程私有的。

9. 程序计数器PC的作用

程序计数器用来记录待执行的下一条指令的地址,CPU是根据时间片来分配资源的,当CPU从A线程切到B线程执行时,就需要记录A线程当前指令所在的位置。 image.png

10. 虚拟机栈(Java栈、Java方法栈)的作用

每一个线程创建后都会申请一个自己单独的栈空间,每一个方法的调用都会对应着一个栈帧。 image.png image.png

11. 局部变量表和操作数栈的作用

虚拟机栈中栈帧的结构: image.png

操作数栈:Operand Stack,也可以叫操作栈,也是栈帧的一部分,操作数栈是用来执行字节码指令过程中用来进行计算的。 image.png

12. JVM解析器执行字节码指令的过程

栈帧里存储着方法的局部变量表(保存着变量的数据)、操作数栈(进行运算时存放数据的空间)、动态连接(指向常量池的引用)和方法返回地址(当前方法返回后的数据存放的地方)信息。 image.png

13. 本地方法栈的作用

image.png

14. 堆中各个区域的作用

image.png image.png

堆中划分新生代和老年代原因? Eden区和Survior划分机制? S1区和S2区划分机制? image.png Refer: JVM基础(二)JVM的内存分区

16. Young GC、Old GC、Full GC的区别

image.png

17. 为什么要进行垃圾回收?

image.png

如何判断一个对象是否应该被回收? 判断一个对象是否应该被回收,主要是看其是否还有引用。判断对象是否存在引用关系的方法包括 引用计数法以及root根搜索方法。

垃圾回收前:垃圾标记阶段 image.png

18. 垃圾标记-引用计数法

image.png

19. 垃圾标记-可达性分析法

image.png

GC Root详细解读: image.png

Refer:GC Roots 是什么?哪些对象可以作为 GC Root?看完秒懂!

20. 垃圾回收-标记清除算法(Mark-Sweep)

image.png

21. 垃圾回收-复制算法(Copying)

image.png

22. 垃圾回收-标记整理算法(Mark-Compact)

image.png

23. 三种常见垃圾回收算法对比

image.png image.png

Refer:JVM基础(四)垃圾回收算法

24. 为什么垃圾收集器都采用分代收集?

image.png

25. 常见的垃圾收集器

image.png

垃圾收集器的升级演化: image.png image.png

Refer:JVM基础(五)垃圾收集器

26. Parallel GC与Parallel Old GC垃圾收集器

image.png

27. CMS垃圾收集器

image.png image.png CMS问题总结: image.png

28. G1(Garbage-First)垃圾收集器

image.png image.png image.png image.png

29. JVM实践观摩(纸上得来终觉浅啊)

Refer:

  • JVM实战:JVM常用监控工具(JDK自带的在线监控指令)
    1. JDK自带的几款在线监控命令(JPS、jstat、jstack、jmap);
    2. JVM离线分析工具(Visualvm)的使用;
    3. 第三方在线监控工具(Arthas)的使用。
  • JVM实战:GC日志解析(如何采集GC日志、各个垃圾回收器GC日志介绍)
  • JVM实战:JVM常用参数配置
  • JVM实战:JVM调优策略
    1. JVM调优核心关注的指标:吞吐量、停顿时间、垃圾回收率;
    2. 常见的调优策略:选择合适的垃圾收集器、增加内存大小、设置符合预期的停顿时间、调整内存区域大小比例、调整对象升老年代的年龄、调整大对象标准、调整GC触发时机、调整JVM本地内存大小、优化业务代码;
    3. JVM调优场景案例(讲得真的很棒!!!)。