有什么方法可以从对象内部判断出我是否超出范围?
我有一个必须关闭的对象。如果没有关闭,则保证泄漏。如果可能,我想尝试自动关闭。
我的一个私有实例变量是一个必须在关闭期间关闭的线程。我猜测线程的存在会导致unclosed对象永远不会被gc'd。
保
答案 0 :(得分:2)
java中没有“超出范围范围”的概念,因为所有对象都在堆上。一旦你说'新',唯一能为你清理的就是gc。你可以使用try / finally,你可以使用终结器等,但就是这样。
你需要阅读有关finalize方法的内容,然后还有关于幻像引用的内容。
http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
答案 1 :(得分:2)
Java没有析构函数。
如果一个对象需要在Java的内存自动垃圾收集之外进行显式清理,那么你可以提供一个显式方法 - 例如close(),terminate()或dispose()。
如果你的线程通过保持对它的引用来阻止对象的垃圾收集,它可以改为保存weak reference,这不会阻止垃圾收集。
使用弱引用,您可以判断引用的对象是否已被垃圾回收。但是,您无法判断垃圾回收是否符合条件。
答案 2 :(得分:1)
不,Java中没有这样的机制。
但是,您可以在关机挂钩中进行紧急清理。有关详细信息,请参阅http://download.oracle.com/javase/1,5.0/docs/guide/lang/hook-design.html。
请注意,这只应被视为最后的手段。
答案 3 :(得分:0)
如果你的意思类似于在C ++中完成RAII的方式,答案是否定的 - 如果你需要做些什么来清理它,Java会坚持你知道什么时候你不再需要它。通常的做法是:
Something s = new Something();
try
{
// do things
}
finally
{
s.close();
}
C#有一个using关键字可以整理一下。
答案 4 :(得分:0)
在研究这个问题时,我确实提出了一个近乎解决方案。基本上,当您创建Runnable时,请获取创建您的线程的副本,并偶尔检查它的堆栈跟踪。如果它变空了你可以安全地假设它们已经完成......或者你可以吗?
private void testThreads() throws InterruptedException {
class ThreadTest implements Runnable {
final Thread maker;
private ThreadTest() {
// Grab the maker's thread.
maker = Thread.currentThread();
}
private boolean makerIsAlive() {
// If maker's stack trace hits empty it is fair to assume they are done.
return maker.getStackTrace().length != 0;
}
public void run() {
// Keep checking the stack using a stacktrace.
while (makerIsAlive()) {
try {
// Get out of here if maker has finished.
// Wait one second.
Thread.sleep(1000);
} catch (InterruptedException ex) {
break;
}
}
System.out.println("====== Maker has finished! Exiting. ======");
}
}
Thread thread = new Thread(new ThreadTest());
thread.start();
// Wait for 10 seconds.
long finishTime = System.currentTimeMillis() + 10 * 1000;
while (System.currentTimeMillis() < finishTime) {
Thread.sleep(500);
}
}