欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Reference

最编程 2024-07-14 12:24:38
...
只要虚拟机检测到对象的任何引用都不会存储在堆中,就可能发生终结:即使该对象的字段仍在使用中,垃圾收集器也可以回收对象,只要该对象无法访问即可。 在诸如以下示例的情况下,这可能具有令人惊讶和不期望的效果,其中与类相关联的簿记通过数组索引来管理。 这里,方法action使用reachabilityFence来确保在关联的ExternalResource上的簿记之前不回收Resource对象; 特别是在这里,为了确保在方法Object.finalize()中没有清除保存ExternalResource的阵列槽,否则可能同时运行。
   class Resource { private static ExternalResource[] externalResourceArray = ... int myIndex; Resource(...) { myIndex = ... externalResourceArray[myIndex] = ...; ... } protected void finalize() { externalResourceArray[myIndex] = null; ... } public void action() { try { // ... int i = myIndex; Resource.update(externalResourceArray[i]); } finally { Reference.reachabilityFence(this); } } private static void update(ExternalResource ext) { ext.status = ...; } } 
这里, reachabilityFence的调用在调用reachabilityFence 之后 update ,以确保在更新之前Object.finalize()没有排除数组插槽,即使对action的调用是最后一次使用此对象。 例如,如果用户程序中的用法具有new Resource().action(); ,而该格式new Resource().action();保留对此Resource其他引用,则可能是这种Resource 虽然这里可能reachabilityFence过分,但reachabilityFence放在finally块中,以确保在方法中的所有路径上调用它。 在具有更复杂控制路径的方法中,您可能需要进一步的预防措施以确保在所有这些reachabilityFence中遇到reachabilityFence

有时可以更好地封装使用reachabilityFence 继续上面的例子,如果对方法update的调用是可接受的,即使终结器已经执行(nulling out slot),那么你可以本地化使用reachabilityFence

   public void action2() { // ... Resource.update(getExternalResource()); } private ExternalResource getExternalResource() { ExternalResource ext = externalResourceArray[myIndex]; Reference.reachabilityFence(this); return ext; } 

在自身确保可达性的结构中不需要方法reachabilityFence 例如,因为通常不能回收被锁定的对象,所以在Resource类(包括finalize )的所有方法中对对象的所有访问都包含在synchronized (this)块中就synchronized (this) (此外,此类块不得包含无限循环,或者本身无法访问,这些都属于“一般”免责声明中的例外情况。)但是,如果此方法效率不高,方法reachabilityFence仍然是更好的选择。理想的,或可能的; 例如,因为它会遇到死锁。