写点什么

【Java 进阶训练营】 JVM 知识总结

作者:wgl
  • 2021 年 12 月 25 日
  • 本文字数:1459 字

    阅读完需:约 5 分钟

重点:1. 类加载器 2.JVM 内存模型 3. GC 4.GC 日志分析和分析工具



  1. 加载(Loading):找 Class 文件

  2. 验证(Verification):验证格式、依赖

  3. 准备(Preparation):静态字段、方法表

  4. 解析(Resolution):符号解析为引用

  5. 初始化(Initialization):构造器、静态变量赋值、静态代码块

  6. 使用(Using)

  7. 卸载(Unloading)


三类加载器

启动类加载器(BootstrapClassLoader)

扩展类加载器(ExtClassLoader)

应用类加载器(AppClassLoader)

加载器特点:

双亲委托

负责依赖

缓存加载



添加引用类的几种方式

1、放到 JDK 的 lib/ext 下,或者-Djava.ext.dirs

2、java–cp/classpath 或者 class 文件放到当前路径

3、自定义 ClassLoader 加载

4、拿到当前执行类的 ClassLoader,反射调用 addUrl 方法添加 Jar 或路径(JDK9 无效)。



JVM 内存整体结构

  1. 每个线程都只能访问自己的线程栈。

  2. 每个线程都不能访问(看不见)其他线程的局部变量。

  3. 所有原生类型的局部变量都存储在线程栈中,因此对其他线程是不可见的。

  4. 线程可以将一个原生变量值的副本传给另一个线程,但不能共享原生局部变量本身。

  5. 堆内存中包含了 Java 代码中创建的所有对象,不管是哪个线程创建的。其中也涵盖了包装类型

  6. (例如 Byte,Integer,Long 等)。

  7. 不管是创建一个对象并将其赋值给局部变量,还是赋值给另一个对象的成员变量,创建的对象都会被保存到堆内存中。

------------

  1. 如果是原生数据类型的局部变量,那么它的内容就全部保留在线程栈上。

  2. 如果是对象引用,则栈中的局部变量槽位中保存着对象的引用地址,而实际的对象内容保存在堆中。对象的成员变量与对象本身一起存储在堆上,不管成员变量的类型是原生数值,还是对象引用。

  3. 类的静态变量则和类定义一样都保存在堆中。

-------------

总结:

  1. 方法中使用的原生数据类型和对象引用地址在栈上存储;对象、对象成员与类定义、静态变量在堆上。

  2. 堆内存又称为“共享堆”,堆中的所有对象,可以被所有线程访问,只要他们能拿到对象的引用地址。

如果一个线程可以访问某个对象时,也就可以访问该对象的成员变量。

如果两个线程同时调用某个对象的同一方法,则它们都可以访问到这个对象的成员变量,但每个线程的局部变量副本是独立的。

---------------

  1. 每启动一个线程,JVM 就会在栈空间栈分配对应的线程栈,比如 1MB 的空间(-Xss1m)。

  2. 线程栈也叫做 Java 方法栈。如果使用了 JNI 方法,则会分配一个单独的本地方法栈(Native Stack)。

  3. 线程执行过程中,一般会有多个方法组成调用栈(Stack Trace),比如 A 调用 B,B 调用 C。。。每执行到一个方法,就会创建对应的栈帧(Frame)。

---------

JVM 栈内存结构


  1. 栈帧是一个逻辑上的概念,具体的大小在一个方法编写完成后基本上就能确定。

  2. 比如返回值需要有一个空间存放吧,每个局部变量都需要对应的地址空间,此外还有给指令使用的操作数栈,以及 class 指针(标识这个栈帧对应的是哪个类的方法,指向非堆里面的 Class 对象)。

-------

JVM 堆内存结构

  1. 堆内存是所有线程共用的内存空间,JVM 将 Heap 内存分为年轻代(Young generation)和老年代(Old generation,也叫 Tenured)两部分。年轻代还划分为 3 个内存池,新生代(Edenspace)和存活区(Survivor space),在大部分 GC 算法中有 2 个存活区(S0, S1),在我们可以观察到的任何时刻,S0 和 S1 总有一个是空的,但一般较小,也不浪费多少空间。

  2. Non-Heap 本质上还是 Heap,只是一般不归 GC 管理,里面划分为 3 个内存池。

  3. Metaspace,以前叫持久代(永久代, Permanentgeneration), Java8 换了个名字叫 Metaspace.CCS, Compressed Class Space,存放 class 信息的,和 Metaspace 有交叉。

  4. Code Cache,存放 JIT 编译器编译后的本地机器代码。



发布于: 3 小时前
用户头像

wgl

关注

正走在系统架构设计师路上的程序员。 2017.12.07 加入

还未添加个人简介

评论

发布
暂无评论
【Java 进阶训练营】 JVM 知识总结