美文网首页
[Java] 观察加载的类的数量的变化

[Java] 观察加载的类的数量的变化

作者: jyjz2008 | 来源:发表于2020-12-12 22:27 被阅读0次

    背景

    • java 命令的一些选项可以帮助我们观察加载的类的名称,
    • jstat 命令的 -class 选项可以显示加载的类的数量。
      结合这两点,我们就可以着手写个小程序,来观察加载的类的数量的变化过程。

    思路

    1. 既然要观察数量变化的过程,那么我们希望在加载类时有明显的停顿(否则变化太快,太难观察)。
      我们可以借助 java.util.Scanner 类的 nextLine() 方法,来让程序进行等待。
    2. 既然是观察变化,那么我们希望能多观察几次,所以可以写个 for 循环来加载若干个类

    代码

    假设当前目录名为 load_test
    我们需要创建

    1. Main.java
    2. generate.sh
      这两个文件。其中 Main.java 用于加载一些类,这些类是通过 generate.sh 文件生成的。
      两个文件的具体内容如下

    Main.java

    import java.util.Scanner;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        int cnt = 10;
        if (args.length > 0) {
            cnt = Integer.parseInt(args[1]);        
        }
        Scanner scanner = new Scanner(System.in);
        for (int i = 1; i <= cnt;i++) {
            scanner.nextLine();
            Class.forName("temp.C" + i);
        }
        // 为了便于观察,不让程序自动结束
        while (true);
      }
    }
    

    generate.sh

    #!/bin/bash
    
    # 如果名为 "temp" 的目录不存在, 则创建它
    # 如果名为 "temp" 的目录已经存在, 则删除这个目录下的文件
    dir_name="temp"
    if [ ! -d "${dir_name}" ];
    then
      mkdir ${dir_name}
    else
      rm ${dir_name}/*
    fi
    
    # cnt 的默认值是 10, 可以被命令行参数替代
    cnt="10"
    if [ "$#" -gt 0 ];
    then
      cnt=${1}
    fi
    
    for i in $(seq 1 ${cnt})
    do
      echo "package ${dir_name};" > "${dir_name}/C${i}.java"
      echo "public class C${i} {}" >> "${dir_name}/C${i}.java"
    done
    
    javac ${dir_name}/*.java
    

    测试

    比如我们想观察5个类的加载情况,那么可以这样操作

    1. 在命令行窗口(简称为窗口 A )中执行 ./generate.sh 5 命令
      生成5个 java 文件
    2. 在窗口 A 中执行 javac Main.java 命令
      编译 Main.java
    3. 在窗口 A 中执行 java -verbose:class -XX:+TraceClassLoading -cp . Main 5 命令
      运行 Main 类
    4. 另开一个命令行窗口(简称为窗口 B ),执行 jps -l 命令,并在输出中找到和 Main 对应的那一行(下图中用红框标出来了)
      找到对应的进程id
    1. 在窗口 B 中执行jstat -class 21844 500命令(注意21844需要替换为和 Main 对应的进程id, 500表示每隔 500ms 输出一次)

      观察加载的类的数量
      我运行时,看到的效果是 571,说明此时已经加载了 571 个类
    2. 在窗口 A 中随便输入一行内容(最省事的办法就是直接敲回车键),然后就会看到有新的类被加载了(红框里是新加载的类,其中 temp.C1 这个类是由 generate.sh 生成的)

      有两个类刚刚被加载
    1. 在窗口 B 中观察,会看到加载的类的数量确实增加了2

      在窗口B进行确认
    2. 在窗口 A 中继续输入内容,然后在窗口 B 中观察

      继续加载其他类

    generate.sh 一共创建了 5 个类,在上图可以看到,这 5 个类都被加载了。在窗口 B 中可以看到加载的类的数量最终变成了 577

    在窗口B进行确认
    1. 由于 Main.java 中的代码不会自动结束,所以需要在窗口 A 中用 Ctrl+C 来终止对应的进程。

    补充说明

    1. 关于 jstat 命令的 -class 选项的介绍可以参考 https://docs.oracle.com/javase/7/docs/technotes/tools/share/jstat.html#class_option
    2. 在窗口 A 执行命令时,只使用 -verbose:class 选项或者 -XX:+TraceClassLoading 选项似乎就能看到同样的效果。关于这两个选项的介绍可以参考 https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html 一文

    相关文章

      网友评论

          本文标题:[Java] 观察加载的类的数量的变化

          本文链接:https://www.haomeiwen.com/subject/qubygktx.html