介绍一下垃圾回收
本系列是为面试,更深的可以参看周志明那本国内最好的JVM书(要出第3版啦)
更好的阅读体验【长期有效】
上一篇文章介绍了一下JVM的内存区域,这一篇文章来介绍一下垃圾回收的概念(涉及的不会很深)。
接着上面一篇的例子:
public class Test {
public static void main(String[] args) {
load();
}
private static void load() {
Manager manager = new Manager();
manager.load();
}
}
整个代码运行流程就是:
main
线程找到main()
入口进入,将main()
压入自己的Java虚拟机栈;- 开始执行
main()
的代码,调用load()
; - 创建
load()
栈帧,压入main
线程的栈; - 进入
load()
,发现局部变量manager
,放入栈帧; - 创建
new Manager()
,在堆内存中分配这个实例对象内存空间; - 同时让
manager
这个局部变量指向堆内存的Manager
; - 接着通过
manager
引用的实例对象去执行他的load()
,实现业务逻辑
到这里,重新理了一下上篇文章的流程。
那一个方法执行完了会发生什么?
之前说过,方法执行完毕,对应的栈帧就会被弹出所在的虚拟机栈。对应这个load()
【load()
里面的load()
】,当它执行完了,栈帧弹出,相应的局部变量就消失了,那么这个指向Manager
实例对象的引用也就消失了,也就是说,当前没有一个变量指向堆内存中的Manager
实例对象。
核心来了,一个实例对象已经没有变量引用它,这个对象实际上已经没用了,那我还留着它干嘛?同时大家知道,内存资源是有限的。我们在Java堆内存里创建的对象,都是占用内存资源。那我们现在应该怎么处理?
也就是今天的主题:JVM的垃圾回收机制。
实际上,只要启动一个JVM进程,就会自带一个垃圾回收的后台线程,这个线程会在后台不断检查堆内存的各个实例对象。当某个实例对象没有任何一个方法的局部变量,也没有任何一个类静态变量,包括常量指向它。那么垃圾回收线程就会把这个实例对象回收掉,从内存中清除掉。
我们刚刚讨论的是堆内存,那么加载到方法区的类呢?
- 首先该类的所有实例对象都已经在堆内存被回收;
- 加载这个类的
ClassLoader
已经被回收; - 该类的
Class
对象没有任何引用
至此,对JVM的核心运行流程,类加载机制,内存区域以及垃圾回收机制有了初步的了解。
dadao你这头像出问题啊小场面,别慌