下面有一张 Java 代码的执行过程图:

代码的执行过程
java
public class Demo {
public static void main(String[] args) {
Student student = new Student();
student.study();
student.hashCode();
student = null;
}
}
class Student {
public void study() {
}
}
根据上面这段代码,具体了解代码的执行过程。
- 执行 javac 命令,将源代码编译为字节码
- 触发类加载机制:创建 JVM,将类信息存入方法区,包括类的继承信息等
- 创建 main 线程,虚拟机栈为 main 方法分配内存(其余线程的内存均为虚拟机栈分配的),然后执行 main 方法
- 在向下执行的过程中,遇到了 Student 这个类。由于这个类还没有加入方法区中,也会触发类加载机制
- 对于 new 出来的对象,会将该对象存入堆内存中
- 对于不需要使用的对象,会在内存不足的时候由垃圾回收器进行回收
- 方法内的局部变量、方法参数使用的是虚拟机栈中的内存
- 调用方法时,会现在方法去中获取方法的字节码指令,由解释器将字节码指令解释为机器码执行
- 当线程发生切换时,需要记录该线程运行到哪一步了,这就需要程序计数器,这样当线程拿到 CPU 资源时就可以继续向下运行
- 对于非 Java 实现的方法调用,使用的内存为本地方法栈
- 当某段代码被频繁调用时,JIT 即时编译器会将这些带啊编译成机器码缓存,提高代码的执行效率
内存溢出
出现 OutOfMemoryError
- 堆内存耗尽:对象越来越多,由于一直在使用,不能被回收
- 方法区内存耗尽:加载的类越来越多,很多框架都会在运行期间动态产生新的类
- 虚拟机栈积累:每个线程最多会占用 1M 的内存,当线程数越来越多但是却一直在运行而不能被销毁
出现 StackOverflowError
- 这个异常大家应该都很熟悉,即 JVM 虚拟机栈中,方法一直递归调用无法退出的情况