gpt4 book ai didi

java - writeObject(this) 暂停程序

转载 作者:行者123 更新时间:2023-11-30 06:40:37 25 4
gpt4 key购买 nike

我正在学习垃圾收集和 Java 对象序列化。在我包含序列化代码之前的代码中,3 个对象正在完成。现在只有一个 finalize() 被调用并在创建 FileOutputStream 对象后进入我的程序正在停止

我已经在 Project 类中实现了 java.io.Serializable,之前当 finalize() 只有一个 println 时,它执行得很好,3 个对象正在完成,但现在它在行后停止

FileOutputStream fout = new FileOutputStream(projectName + ".bin");

类(class)项目:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Project implements Serializable {

private static final long serialVersionUID = 4721106266710903835L;
int projectID;
String projectName;

public Project() {
super();
}

public Project(int projectID, String projectName) {
super();
this.projectID = projectID;
this.projectName = projectName;
System.out.println("Object created : " + this.projectID);
}

@Override
protected void finalize() {
try {
super.finalize();
} catch (Throwable e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(this.projectID + " Deallocated");

try {

System.out.println("Test 0");
FileOutputStream fout = new FileOutputStream(projectName + ".bin");
System.out.println("Test 1");
ObjectOutputStream oout = new ObjectOutputStream(fout);
System.out.println("Test 2");

oout.writeObject(this);
oout.flush();
System.out.println("Done");

fout.close();
oout.close();
}
catch(IOException e) {
e.printStackTrace();
System.out.println("Exception");
}

}

}

项目控制类:

public class ProjectControl {

public static void main(String[] args) {
Project p = new Project(100, "ABC");
System.out.println(p.projectID);
System.out.println(p.projectName);

p = null;

Project p1 = new Project(200, "DEF");
Project p2 = p1;

p1 = null;
System.out.println(p2.projectID);

p2 = new Project(300, "GHI");
System.out.println(new Project(400, "GHI").projectID);
System.gc();
}
}

最初 finalize() 每次打印运行 3 次

<<projectID>> deallocated

现在编程一次就停止了。在遇到该行之前,只有测试 0 被打印一次

FileOutputStream fout = new FileOutputStream(projectName + ".bin");

最佳答案

很难说发生了什么,但我的猜测是 JVM 在调用对象的 finalize 方法时退出。 (finalize() 调用将在守护程序终结器线程上运行。当 JVM 检测到所有非守护程序线程都已终止时,它会启动有序关闭过程。)

为了使您的方案可靠地工作,需要有 100% 的防弹保证,确保您的 finalize 方法将在 JVM 退出之前完成。 JVM 不提供此类保证。相反javadoc对于 finalize() 说:

[T]here are no guarantees regarding the timing of finalization. The finalize method might be called on a finalizable object only after an indefinite delay, if at all.

JLS 12.6说:

The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused.

如果您依靠终结来保存对象的状态,那么您的立场就非常不稳定。


曾经有一个名为 java.lang.System.runFinalizersOnExit 的方法可能在理论上有所帮助。然而,它在 Java 1.2 中被弃用,并在 Java 11 中被删除。根据 javadoc:

This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.

因此,如果我们从表面上接受该警告,则该方法不会为您提供 100% 可靠的持久性,甚至可能导致更严重的问题。


finalize 方法和机制在 Java 9 中被标记为已弃用,并且可能会在未来的 Java 版本中删除。当这种情况发生时,对于任何依赖最终确定的应用程序来说,这将是“道路的尽头”。您应该将此视为一个重要提示,您应该重新考虑您的策略。


如果尽管我上面已经说过,您仍然想要一种使用终结器“让它工作”的方法,我认为没有可靠的方法。

关于java - writeObject(this) 暂停程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57687870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com