04_JVM 的垃圾回收机制
670字约2分钟
2024-08-10
一个方法执行完毕之后会怎样
我们看一下下面这个代码,loadMessageFromDisk()
方法执行完会发生什么
public class Order {
public static void main(String[] args) {
loadMessageFromDisk();
}
public static void loadMessageFromDisk() {
MqManager mqManager = new MqManager();
mqManager.load();
}
}
当 mqManager.load()
这行代码执行完毕,相应的也是 loadMessageFromDisk()
方法执行完毕,此时就会把 loadMessageFromDisk()
方法对应的栈帧从 main
线程的 Java虚拟机
出栈
loadMessageFromDisk()
方法出栈,我们就会发现栈帧里面的局部变量 mqManager
也就没有了,也就是说,没有任何一个变量指向 Java堆内存
中的 MqManager
实例对象了,变化过程如下图所示
不再需要的对象如何处理
我们在 Java堆内存 里创建的对象都是会占用内存资源的,而且内存资源是有限的,像上面的 MqManager
实例对象已经没有地方引用他了,这个对象实际上已经没有用了
JVM
本身是有垃圾回收机制的,是一个后台自动运行的线程,只要启动一个 JVM
进程,他就会自带一个垃圾回收的后台线程
这个线程在后台不断检查 JVM堆内存
中的各个实例对象,如果某个实例对象没有任何一个方法的局部变量,也没有任何一个类的静态变量以及常量等地方指向他,这些不在被指向的对象实例就是 JVM
中的垃圾,就会定期被后台垃圾回收线程清理掉,不断释放内存资源
思考环节
1、Java堆内存 里的对象会被回收掉,那么加载到方法区的类会被垃圾回收吗?什么时候回收?
满足以下三个条件,方法区的类会被回收
1、首先该类的所有实例对象都已经从
Java堆内存
里被回收2、其次加载这个类的
ClassLoader
已经被回收3、最后,对该类的
Class
对象没有任何引用
2、方法执行完毕,引用消失,堆内存还未必消失。比如在做报表导出的时候,就会在 for 循环中不断创建对象,很容易造成堆溢出,如何解决这个问题?
不建议在 for
循环中创建对象,可以在循环外创建一个对象,for
循环中对一个对象反复赋值使用