Java 跟踪资源并在不必要时卸载它们
我一直在尝试用Java设计一个系统,在这个系统中,我可以跟踪从磁盘加载的图像和音频文件等资源,并在没有引用的情况下卸载它们 在C++中,i可以重写删除操作符,这样可以减少引用。 但是Java使用自动垃圾收集,当对象没有引用时,它会销毁对象 因为我跟踪resourcemanager中的所有资源,所以对对象的引用永远不会为null,因此如果不需要资源,也永远不会卸载这些资源 是否有一种方法可以跟踪对象,同时在它们没有实体引用的情况下删除它们Java 跟踪资源并在不必要时卸载它们,java,memory-management,garbage-collection,Java,Memory Management,Garbage Collection,我一直在尝试用Java设计一个系统,在这个系统中,我可以跟踪从磁盘加载的图像和音频文件等资源,并在没有引用的情况下卸载它们 在C++中,i可以重写删除操作符,这样可以减少引用。 但是Java使用自动垃圾收集,当对象没有引用时,它会销毁对象 因为我跟踪resourcemanager中的所有资源,所以对对象的引用永远不会为null,因此如果不需要资源,也永远不会卸载这些资源 是否有一种方法可以跟踪对象,同时在它们没有实体引用的情况下删除它们 我听说解构器不安全,所以这也不是一个选项在您的resour
我听说解构器不安全,所以这也不是一个选项在您的resourcemanager中使用WeakResfence,例如WeakHashMap 您可以在此处找到WeakReference(和其他引用,如Softreference)的良好解释: 简说:
弱引用是不强制对象留在内存中的引用。如果没有对该对象的强引用,但resourcemanager中仍有弱引用,则该对象仍可用于垃圾回收,并可由垃圾回收器删除。您可以强制资源用户在使用完资源后手动
处置他们使用的资源,类似于java.io
包中的close()
方法
在这种dispose
方法中,您可以减少一个计数器,当达到零时,您可以显式释放底层资源。Java 7确实有一种允许基于范围的简洁方法,将资源的关闭与特定程序范围的关闭联系起来。然而,据我所知,由于Java对象破坏的不确定性,基于对象的资源管理(您似乎正在描述)是不可能的
对于更复杂的场景,资源关闭必须发生在打开资源的原始范围之外(例如在另一个线程上或在接收到事件之后),必须执行手动关闭。遗憾的是,引用计数实现(C++通用)是不可能的。托管GC语言具有非确定性破坏,因此您不能将关闭资源与销毁对象联系起来。在爪哇编程中,C++是我最不想做的事情之一,没有自动的方法。您必须实现某种类型的重新计数。使用资源的所有内容都必须在开始时调用acquire
,最后调用release
。WeakRef仍然无法解决及时处置问题。它将资源生命周期与对象生命周期相耦合,从而为资源泄漏打开了大门。这适用于不同的用例,例如,您可能希望保留对象引用以进行缓存,但不阻止GC。在OP描述的场景中,它对资源管理没有帮助。@Pablo-弱引用只能在对象有其他引用时使用(一旦所有这些引用都消失,WR就不能用于关闭资源等任何事情)。此外,在所描述的场景中,您希望及时关闭资源,而不是在GC发生时(可能是在对象丢失最后一个引用后的几天内)。@Marko Topolnik:我认为在所描述的场景中不需要及时处理OP。只要有内存需要,GC就会运行,如果没有对对象的强引用,GC就会处理该对象。在这种情况下,我个人有一个SWT句柄泄漏。当您拥有数百MB的堆,但UI资源只有64K个句柄时,您很快就会感受到资源管理和内存管理之间的区别。