Bean 何时被 GC

2021-01-29

当一个对象要被 JVM 垃圾收集器回收掉时会执行对象的 finalize 方法,所以 User 类对该方法进行重写

package constxiong;

public class User {

	@Override
	protected void finalize() throws Throwable {
		System.out.printf("我(id:%d)要被 gc 回收了\n", id);
		super.finalize();
	}

	private Integer id;

	private String name;

	public User(Integer id) {
		this.id = id;
		System.out.println("init id:" + id);
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User{" +
				"id=" + id +
				", name='" + name + '\'' +
				"}";
	}
}

 

在 spring xml 配置文件里配两个 bean:user1、user2

<bean id="user1" class="constxiong.User">
	<constructor-arg name="id" value="1"></constructor-arg>
	<property name="name" value="constxiong"/>
</bean>

<bean id="user2" class="constxiong.User">
	<constructor-arg name="id" value="2"></constructor-arg>
</bean>

 

测试类

/**
 * 测试 Bean gc
 * @author ConstXiong
 */
public class Test {
	
	public static void main(String[] args) throws InterruptedException {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring-bean-gc.xml");
		//刷新 ioc 容器
		context.refresh();
		System.out.println(context.getBean("user1", User.class));
		BeanDefinitionRegistry registry = (DefaultListableBeanFactory)context.getBeanFactory();
		registry.removeBeanDefinition("user1");
		Thread.sleep(3000L);
		//关闭 ioc 容器
		context.close();
		System.out.println("ioc 容器关闭");
		System.gc();
		Thread.sleep(3000L);
	}
}

 

打印结果

init id:1
init id:2
init id:1
init id:2
User{id=1, name='constxiong'}
ioc 容器关闭
我(id:1)要被 gc 回收了
我(id:2)要被 gc 回收了
我(id:1)要被 gc 回收了
我(id:2)要被 gc 回收了

 

看到以上情况可能会比较惊讶,说明一下:

ConstXiong 备案号:苏ICP备16009629号-3