Java - Object#finalize在JDK9中被标记废弃了!
时间:2022年12月6日01:34:10
目录:
① 为什么要废弃?
② 废弃后,使用什么方式主动监测对象是否被回收?
一、为什么要废弃?
⚡注意:废弃≠移除
二、可以使用什么方法检测对象被回收呢?(使用Cleaner✔️)
- 可参考源码:DirectByteBuffer⚡⚡⚡
- import jdk.internal.ref.Cleaner;
- –add-opens java.base/jdk.internal.ref=ALL-UNNAMED → 请继续阅读【三】,将会使用另一个Cleaner🚀
Cleaner使用示例:
import java.util.concurrent.TimeUnit;
public class CleanerTest {
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
System.out.println(user1);
System.out.println(user2);
System.gc();
user1 = user2 = null;
System.gc();
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { throw new RuntimeException(e); }
}
}
或者
public class CleanerTest {
public static void main(String[] args) {
try (
User user1 = new User();
User user2 = new User();
) {
System.out.println(user1);
System.out.println(user2);
}
}
}
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import jdk.internal.ref.Cleaner;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Closeable;
@EqualsAndHashCode
public class User implements Closeable {
private final Cleaner cleaner;
private final _User user;
public User() {
user = new _User();
cleaner = Cleaner.create(this, user);
}
@Override
public String toString() {
return user.toString();
}
@Override
public void close() {
cleaner.clean();
}
@EqualsAndHashCode
@ToString
private static class _User implements Runnable {
private final String id;
public _User() {
id = IdWorker.get32UUID();
}
@Override
public void run() {
System.out.printf("哦不! 我(%s)要被回收了!%n", id);
}
}
}
三、两个Cleaner!(推荐使用 java.lang.ref.Cleaner + Closeable)
1.使用Cleaner示例(推荐):
import java.util.concurrent.TimeUnit;
public class CleanerTest {
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
System.out.println(user1);
System.out.println(user2);
System.gc();
user1 = user2 = null;
System.gc();
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { throw new RuntimeException(e); }
}
}
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.lang.ref.Cleaner;
@EqualsAndHashCode
public class User {
private final String id;
private final Cleaner cleaner = Cleaner.create();
private final Cleaner.Cleanable cleanable;
public User() {
this.id = IdWorker.get32UUID();
cleanable = cleaner.register(this, new State());
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
'}';
}
@EqualsAndHashCode
@ToString
private static class State implements Runnable {
public State() {
System.out.println("[构造中...]: 这里一般通过参数获取堆外内存地址等信息。");
}
@Override
public void run() {
System.out.println("[回收中...]:这里一般根据堆外内存地址等信息,完成堆外内存释放。");
}
}
}
↓
官方还推荐将要特定被回收的类实现Closeable接口,用于资源自动回收
↓
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Closeable;
import java.lang.ref.Cleaner;
@EqualsAndHashCode
public class User implements Closeable {
private final String id;
private final Cleaner cleaner = Cleaner.create();
private final Cleaner.Cleanable cleanable;
public User() {
this.id = IdWorker.get32UUID();
cleanable = cleaner.register(this, new State());
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
'}';
}
@Override
public void close() {
// Cleaner.Cleanable
cleanable.clean();
}
@EqualsAndHashCode
@ToString
private static class State implements Runnable {
public State() {
System.out.println("[构造中...]: 这里一般通过参数获取堆外内存地址等信息。");
}
@Override
public void run() {
System.out.println("[回收中...]:这里一般根据堆外内存地址等信息,完成堆外内存释放。");
}
}
}
public class CleanerTest {
public static void main(String[] args) {
try (
User user1 = new User();
User user2 = new User();
) {
System.out.println(user1);
System.out.println(user2);
}
}
}