JVM - 架构


前言

基于 JDK 8

JVM

类文件格式

The class File Format

Java 之所以可以“一次编译,到处运行”,一是因为 JVM 针对各种操作系统、平台都进行了定制;二是因为无论任何平台,javac 编译生成固定格式的字节码文件(*.class)供 JVM 使用。

格式:

  1. 魔数(Magic)
  2. 版本号(Version)
  3. 常量池(constant_pool)
  4. 访问标志(access_flag)
  5. 当前类索引(this_class)
  6. 父类索引(super_class)
  7. 接口索引(interfaces)
  8. 字段表(fields)
  9. 方发表(methods)
  10. 附加属性(attributes)
ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count - 1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

类加载器

# 监控类的加载
-XX:+TraceClassLoading
-XX:+TraceClassUnloading

Creation and Loading

要执行 class 文件就需要先将其读入内存,这个是由类加载器完成的。

类加载器类型:

名称说明
Bootstrap ClassLoaderC++ 实现,无法访问
Extension ClassLoader父类为 Bootstrap,显示为 null
Application ClassLoader父类为 Extension
自定义 ClassLoader父类为 Application
package xianzhan.jdk8;

/**
 * @author xianzhan
 * @since 2022-06-11
 */
public class Main {

    public static void main(String[] args) {
        LeeClassLoader loader = new LeeClassLoader();
        System.out.println(loader.getClass().getName());
        ClassLoader p = loader.getParent();
        while (p != null) {
            System.out.println(p.getClass().getName());
            p = p.getParent();
        }
    }
}

class LeeClassLoader extends ClassLoader {

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println("重写该方法. name: " + name);
        return super.findClass(name);
    }
}

ClassLoader

运行时数据区

# 设置线程栈大小,限制栈的深度
-Xss1M

# 逃逸分析
# 开启逃逸分析 JDK 1.6 默认开启
-XX:+DoEscapeAnalysis
# 查看逃逸分析的筛选结果
-XX:+PrintEscapeAnalysis

# 元空间
# 设置分配的 Metaspace 的大小,Metaspace 将在首次超过垃圾收集时触发垃圾收集。
# 垃圾收集的阈值取决于使用的元数据量而增加或减少。默认大小取决于平台。
-XX:MetaspaceSize=size
# 设置可以分配给 Metaspace 的最大本机内存。默认情况下,大小不受限制。
# 应用程序的 Metaspace 量取决于应用程序本身,其他正在运行的应用程序以及系统上可用的内存量
-XX:MaxMetaspaceSize=size

# 堆
# JVM 启动时, 所占据的操作系统内存的大小
-Xms2G
-XX:InitialHeapSize=2G
# 最大堆是指新生代和老年代的大小之和的最大值
# 它是 Java 应用程序的堆上限
-Xmx2G
-XX:MaxHeapSize=2G
# 用于设置新生代的大小
# 新生代越大, 老年代越小
# 新生代一般设置为整个堆空间的 1/4 到 1/3 左右
-Xmn512M
# -Xmn 的效果等同于设置了相同的 -XX:NewSize 和 -XX:MaxNewSize
# 下面参数不一致时, 可能会导致内存震荡, 从而导致不必要的开销
# 设置新生代的初始大小
-XX:NewSize
# 设置新生代的最大值
-XX:MaxNewSize
# 设置新生代中, eden 空间和 s0 空间的比例关系
# -XX:SurvivorRatio=eden/s0=eden/s1
-XX:SurvivorRatio=8
# 设置 survivior 区的可使用率
# 当 survivior 区的空间使用率达到这个数值时, 会将对象送入老年代
-XX:TargetSurvivorRatio
# 设置新生代和老年代的比例
# -XX:NewRatio=老年代/新生代
-XX:NewRatio=2
# 设置堆空间的最小空闲比例
# 当堆空间的空闲内存小于这个数值时, JVM 便会扩展堆空间
-XX:MinHeapFreeRatio
# 设置堆空间的最大空闲比例
-XX:MaxHeapFreeRatio

java
Run-Time Data Areas
JEP 122: Remove the Permanent Generation
JEP 147: Reduce Class Metadata Footprint
JEP 149: Reduce Core-Library Memory Usage

JDK 8 运行时数据区里的方法区,由之前的永久代(Permanent Generation)改为元空间(Metaspace)。

资源

JVM 规范

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值