为了理解 Java 中的弱引用,我不得不查阅 Java 语言规范。以下部分来自第 12.6 节,让我感到困惑:
一个未终结的对象从来没有自动调用它的终结器;已完成的对象已自动调用其终结器。可终结对象从未自动调用其终结器,但 Java 虚拟机可能最终会自动调用其终结器。
那么 unfinalized 和 finalizable 对象之间的正式区别是什么?从引用看来,如果 unfinalized 和 finalizable 是不同的,那么对于一个 unfinalized 对象来说,JVM 最终可能会调用它的终结器是不正确的。有点混乱,或者我还有一些英语语义要研究;)
链接到 Java 规范中的部分:Implementing Finalization
为什么我的终结器没有被调用?
using System;
class Program
{
static void Main(string[] args)
{
Test test = new Test();
}
}
class Test
{
public Test()
{
Console.WriteLine("Start");
}
~Test()
{
Console.WriteLine("End");
}
}
Run Code Online (Sandbox Code Playgroud)
我在网上搜索了一下,没有找到合适的。我期待最后控制台输出“End”。
由于该过程将被操作系统杀死,并且所有分配的内存都将被回收,是否可以在单元定型部分中释放对象/资源?
例如,
unit Threading;
interface
implementation
var threadpool: ThreadPool;
initialization
threadpool := ThreadPool.Create;
finalization
threadpool.Free; // is it OK to remove this?
end.
Run Code Online (Sandbox Code Playgroud) 我的Delphi 7项目中有很多单元都有"finalization"部分.
我如何确保最后执行一些代码?
我试图在.dpr文件中编写一个"终结"部分,但它没有编译.
我总是将动态数组的初始化与终结器配对,形式为
finally
SetLength(Array, 0);
end;
Run Code Online (Sandbox Code Playgroud)
确切地知道数组何时被“销毁”感觉更自然,并且如果需要的话,可以通过已经拥有“最终”可用的方式更平滑地从数组过渡到 TList。
然而这种方法使源代码更加缩进。这种方法有什么缺点吗——可读性、可维护性、可扩展性、性能、易出错性?
我写的示例代码:
var
A1: array of Integer;
A2: array on Boolean;
A3: array of string;
begin
SetLength(A1, 10);
try
...
SetLength(A2, 20);
try
...
SetLength(A3, 30);
try
...
finally
SetLength(A3, 0);
end;
finally
SetLength(A2, 0);
end;
finnally
SetLength(A1, 0);
end;
end;
Run Code Online (Sandbox Code Playgroud) 我的问题是,我在第 0 代中有对象,并且我还重写了终结方法。
当gc收集gen0时,发现它必须完成,所以不立即释放它们,并将这些对象提升到gen1?因此,只有当 gc 收集到 gen1 时,这些才会被释放。假设这些对象不会被再次使用,它们就是垃圾
谢谢!