问题标签 [finalization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java:参考对象的 API 文档需要澄清
我了解了 Java 中引用对象的要点,以及软引用对象、弱引用对象和幻像引用对象之间的基本区别。
但是,我不完全理解 API 文档中的以下几点
来自WeakReference<T>的 API 文档:
“弱引用对象,不会阻止它们的引用对象被最终化,最终化,然后被回收。”
现在, API 文档中的任何地方都没有解释粗体字的术语,所以我想知道它们的确切含义,特别是与或多或少不推荐使用
Object.finalize()
的方法的终结概念有关。来自Reference<T>的 API 文档:
public void clear()
:“此方法仅由 Java 代码调用;当垃圾收集器清除引用时,它会直接清除引用,而不调用此方法。”public boolean enqueue()
:“此方法仅由 Java 代码调用;当垃圾收集器将引用入队时,它直接这样做,而不调用此方法。”同样,我不知道上面 2 句引号中的“Java 代码”是什么意思:我无权访问的 JVM 内部代码?或者,我具有只读/浏览访问权限的 JDK 代码?或者,最终用户自己的 Java 代码?
“直接,不调用这个方法”部分告诉我JVM不需要调用这些方法。另一方面,“仅由 Java 代码”部分告诉我,它不是最终用户的 Java 代码,而是 JVM 的(如果它意味着最终用户代码,那么我们会发现这个短语在所有几乎每个 Java 类的每个方法的 API 文档!)。那么哪种解释是正确的,谁能调用这个函数呢?
java - 在 Java 中如何将对象标记为 finalized(以便第二次不会调用 finalize 方法)?
主要问题在主题中,但让我展示一下我对 Java 完成过程的看法,以便我可以再问你一点。
那么 gc 通过标记所有活动对象开始垃圾收集。当所有可达对象都被标记为“活动”时。所有其他对象都无法访问。下一步是检查每个无法到达的对象,并确定它是否可以立即被清扫,或者应该首先完成。如果对象的 finalize 方法有一个主体,那么 gc 会考虑下一个方法,那么这个对象是可终结的并且应该被终结;如果对象的 finalize 方法有一个空主体(受保护的 void finalize(){ }),那么它是不可终结的,现在可以被 gc 清除。(我说得对吗?)
所有可终结的对象都将放在同一个队列中,以便稍后一一终结。据我了解,一个可终结的对象在等待轮到它最终确定时可能会花费大量时间被放入队列中。这可能会发生,因为通常只有一个名为 Finalizer 的线程从队列中获取对象并调用它们的 finalize 方法,并且当我们在某个对象的 finalize 方法中进行一些耗时的操作时,队列中的其他对象将等待很长时间才能完成。好吧,当一个对象已经完成时,它会被标记为 FINALIZED 并从队列中删除。在下一个垃圾收集过程中,收集器将看到该对象(再次)无法访问并且具有非空的 finalize 方法(再次)所以该对象应该被放入队列中(再次) - 但它不会因为收集器以某种方式看到这个对象被标记为 FINALIZED。(这是我的主要问题:这个对象以什么方式被标记为 FINALIZED,收集器如何知道这个对象不应该再次被最终确定?)
java - Java 终结队列和内存泄漏
如何获取所有等待完成的对象的列表?,以便我可以手动完成它。
目前我没有得到直接的方法来让所有对象等待完成。
java - 在使用 PhantomReferences 完成时,我会避免使用反射吗?
假设我创建了一个实现 Closable 的类 MyClass。所以在 close() 方法中,我将释放一些非常重要的资源。好吧,因为它是非常重要的资源,所以我创建了某种安全网络(如 Effective Java 中推荐的那样)。这里是:
一开始我很高兴,但后来我读到终结器并不那么酷,而且有一个像 PhantomReference 这样很酷的工具。所以我决定更改我的代码以使用 PhantomReference 而不是 finalize() 方法。我创建了 CustomPantom 扩展了 PhantomRefernce。这里是:
因此,正如我所见,我可以获得对我的对象的引用的唯一方法是使用反射并从 Reference 类中的引用字段中获取 if。这是从清理方法调用 MyClass.close() 的唯一方法吗?
PS我没有在这里发布所有代码,但我测试了它并且一切正常。ReferenceQueue由PhantomReferences填充,然后我可以一一获取并调用清理方法。但是我看不到如何在不使用反射的情况下解决上述问题。
delphi - 过早调用的日志单元的最终确定
我正在运行一个 ISAPI 服务,它运行IdHTTPWebBrokerBridge
(用于作为独立 EXE 调试)以及在 Apache 中运行mod_isapi
(在生产环境中)。
在销毁 web 模块时记录一些内容时,我发现了以下问题:
-
LogFactory.pas
在初始化时创建对象GlobalLogFactory
并在完成时销毁它。
但LogFactory.pas:finalization
被称为 BEFORE TMyWebModule.WebModuleDestroy
,因为它仅包含在本单元中,因此最终确定将以相反的顺序完成。
我怎样才能确保我的GlobalLogFactory
将被正确释放(即 FastMM 不会警告内存泄漏),但同时,我想让所有销毁/终结程序有机会记录一些东西?
一种解决方法是LogFactory.pas
在 DPR 文件中明确包含作为第一个单元。但我不太喜欢这样,因为这个 Log-Unit 应该在许多项目中使用,并且只需将它包含在需要记录某些内容的单元中就可以使用它。将此日志单元放在每个可能希望在未来记录某些内容的 DPR 中是一项巨大的工作,而忘记它可能会给不知道我做了什么/需要什么的开发人员带来问题。
delphi - 正在手动调用 SetLength(array, 0); 有缺点吗?
我总是将动态数组的初始化与终结器配对,形式为
确切地知道数组何时“被破坏”并允许我在需要时通过已经有一个“finally”可用来更平滑地从数组过渡到 TList 感觉更自然。
然而,这种方法使源代码更加缩进。这种方法有什么缺点吗——可读性、可维护性、可扩展性、性能、错误倾向?
我写的示例代码:
c++ - C++:派生类对象的终结顺序
我知道类对象的完成顺序如下:
- 执行析构函数体
- 销毁对象(即释放用于数据成员的内存)
现在有人问我派生类对象的终结顺序。我想它是完全一样的,但是在执行上述步骤之后,基类对象的析构函数是否也被调用了?
我不这么认为,但想确定考试。
谢谢你的帮助 :)
java - 可最终确定的对象的前期成本是多少?
Java 中可终结对象的讨论通常会讨论当可终结对象(及其相关资源)无法快速垃圾回收时发生的常见间接成本。
目前,我对最终化的实际直接成本更感兴趣,无论是在内存方面还是在对象分配时间方面。我在很多地方都看到过对这种成本存在的间接引用,例如,Oracle 关于终结内存保留问题的文章指出:
分配时
obj
,JVM 内部记录是obj
可终结的。这通常会减慢现代 JVM 拥有的其他快速分配路径。
JVM 如何记录对象实例是可终结的,这样做的内存和性能成本是多少?
对于那些对我的特定应用感兴趣的人:
我们生产并保留了数百万个令人难以置信的轻量级物体;向这些对象添加单个指针的成本非常高,因此我们做了相当多的工作来从它们中删除指针,而不是使用更小的数字 id 打包到字段的位子集中。解包数字允许从使用 Map 存储它们的池中检索具有该 id 的共享不可变属性。
剩下的问题是如何处理不再使用的属性值的垃圾收集。
已考虑的一种策略是使用引用计数。当创建对象并检索一个值的池 id 时,该值的引用计数会增加;当不再使用时,必须递减。
确保发生这种递减的一种选择是添加以下 finalize 方法:
但是,如果可终结的行为本身就意味着必须保留一个指向对象的附加指针,那么对于此应用程序而言,可终结的前期成本将被认为是高昂的。如果这意味着必须分配额外的对象,那几乎肯定会太高......因此,我的问题是:最终化的直接前期成本是多少?
python - PyQt5 和初始化/完成 python 解释器
我有一个可以使用 Python 宏进行扩展的应用程序。由于不经常使用python,因此对于每个宏,我都会初始化python解释器,运行宏,然后完成解释器。
一切正常,除了 PyQt5:在第一个宏结束后,所有类都从 PyQt5 模块中消失。我猜这是静态变量的问题,并且 PyObject 在最终确定时被破坏。但是除了永远不要杀死 Python 解释器之外,还有什么可做的吗?
这是我的宏的代码:
在第一次运行时,我有对话框,但在任何其他运行时,我都会收到错误:
编辑:也许另一种看待这一点的方式是:有没有办法显式地实例化 PyQt5 的所有类,就像你必须调用import_array
初始化numpy
库一样?
c# - 如何列出 GC 终结列表中的所有对象?
我的程序崩溃了,它是 VS 的可视化工具,所以调试起来非常困难,我尝试制作转储并使用 WinDbg 研究它,但没有成功。
所以,现在我尝试以编程方式将手放在该列表上,但我不知道如何。谢谢。