让我们先来简单了解一下JVM。
JVM功能:
1、解释和运行:对字节码文件中的指令,实时的解释成机器码让计算机执行。
2、内存管理:自动为对象、方法等分配内存;自动的垃圾回收机制,回收不再使用的对象。
3、即时编译:对热点代码进行优化提升执行效率。
JVM组成:
1、类加载器classLoader:加载class字节码文件中的内容到内存中。
2、运行时数据区域(JVM管理的内存):负责管理JVM使用到的内存,比如创建对象和销毁对象。
3、执行引擎(即时编译器,解释器,垃圾回收器等):将字节码文件中的指令解释成机器码,同时使用即时编译器优化性能。
4、本地接口:调用本地已经编译好的方法,比如虚拟机中提供的c/c++的方法。
字节码文件,由5个部分组成:
基础信息:魔数、字节码文件对应的Java版本号访问标识父类和接口
魔数:文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件内容。 软件打开的文件的头几个字节(文件头)去校验文件的类型,如果文件软件不支持该种类型就会出错。修改文件扩展名是不能修改文件头的。 在Java字节码文件中的文件头就被称为魔数,必须是0xcafebabe。
主副版本号:指的是编译字节码文件的jdk版本号。主版本号用来标识大版本号。副版本号就是当主版本号相同时作为区分不同版本的标识,一般只需要关心主版本号。1.2之后大版本计算方法是:主版本号-44,比如主版本号是52就是jdk8。 版本号的作用主要是判断当前字节码的版本和运行时的jdk是否兼容。
常量池:保存了字符串常量、类或接口名、字段名主要在字节码指令中使用。作用是:避免相同内容重复定义,节省空间。
字段:当前类或接口声明的字段信息。
方法:当前类或接口声明的方法信息字节码指令
属性:类的属性,比如源码的文件名内部类的列表等等。
查看字节码文件常用工具:
1、本地文件用java-v命令:是jdk自带的反编译工具,可以通过控制台查看字节码文件的内容。适合在服务器上查看字节码文件的内容。如果是jar包需要先使用jar-xvf命令解压。
2、开发环境用idea的jclasslib插件:
jclasslib下载:打开idea的setting,
jclasslib的使用:
首先在idea中写好一份简单代码:
package org.example;
public class text1 {
static {
System.out.println("text1...静态代码块");
}
public static void main(String[] args) {
int i=0;
System.out.println(i);
}
}
首先选中要查看的类, 然后点击view选项中的show bytecode with jclasslib
就可以查看了。
3、服务器环境用arthas:arthas是 一款先上个监控诊断产品,通过全局视角实时查看应用load、内存、gc、线程的状态信息(即查看运行中程序的字节码文件),并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。
我们下载了arthas的jar包后,需要在我们安装的jdk路径下运行java-jar运行该jar包,否则会报错找不到某个文件。我用的mac.
首先先加上一行代码,让程序一直处于运行状态。
package org.example;
import java.io.IOException;
public class text1 {
static {
System.out.println("text1...静态代码块");
}
public static void main(String[] args) throws IOException {
int i=0;
System.out.println(i);
System.in.read();
}
}
运行该程序。
然后我们就可以去启动arthas jar包了,我把arthas jar包放在了桌面上。
先切换到Desktop界面,然后再用jdk路径的java -jar命令运行jar包。
然后回车执行:
图中它返回给我4个线程,前面的数字是它们的序号,冒号后面是线程号,线程的路径和类名。
我们刚刚执行的代码是org.example.text1类。我们想查看该类,就输入它的序号 4 然后回车就可以了
这就是启动成功了。
arthas命令:
dashboard 命令:当前系统的实时数据面板,启动后按ctrl+c退出。参数-i :设置刷新实时数据的时间间隔(ms),-n :刷新次数。 dashboard -i 1000 -n 1 意思是1s后刷新一次打开数据面板。
dump加载类的字节码文件到特定路径。参数 -d :设置类文件的目标目录。
jad :将一个运行中的类的字节码信息反编译称源代码。
classloader :查看classloader的详细信息。