c# - 是否可以跟踪类的当前实例数?
问题描述
在 .NET 中,我知道有一个垃圾收集器可以管理程序执行期间正在使用的内存。这意味着对象将在未使用时被清理。
我想知道是否可以在某个类中保留一个静态计数器,当该类的实例被创建或垃圾收集时自动更新。例如,如果我创建了某个CountableInstance
类的一些实例,那么它们每个都可以有一个根据创建时间InstanceIndex
跟踪它们当前位置的实例。
这样的流程可能如下所示:
- 程序开始
CountableInstance ctble0
是用InstanceIndex == 0
CountableInstance ctble1
是用InstanceIndex == 1
CountableInstance ctble2
是用InstanceIndex == 2
CountableInstance ctble1
未使用并收集垃圾
ctble0
的索引保持不变ctble2
的索引变为1
- 节目结束
我猜想跟踪CountableInstance
实例的数量会是这样的:
public class CountableInstance
{
public static int total = 0;
public CountableInstance()
{
InstanceIndex = total;
total++; // Next instance will have an increased InstanceIndex
}
public CountableInstance(...) : this()
{
// Constructor logic goes here
}
public int InstanceIndex { get; private set; }
}
这会处理有多少实例,并且还会为每个新对象分配正确的索引。然而,这个实现错过了当实例被垃圾收集时应该发生的逻辑。
如果可能,我该如何实施?跟踪使用特定接口的对象的实例是否也有效?
解决方案
您可以实现以下要点,但这似乎是 IMO 的一个坏主意;尤其是:
- 终结器不是免费的(也不是
IDisposable.Dispose()
) - 您可以在不运行构造函数的情况下创建对象(如果您足够努力的话)
无论如何,代码:
public class CountableInstance
{
static int s_Total, s_Alive;
public CountableInstance() {
// need a separate total vs alive so we don't give duplicate
// InstanceIndex, at least for the first 4 billion objects
InstanceIndex = Interlocked.Increment(ref s_Total);
Interlocked.Increment(ref s_Alive);
}
~CountableInstance() {
Interlocked.Decrement(ref s_Alive);
}
public int InstanceIndex { get; }
public static int Alive => Volatile.Read(ref s_Alive);
public static int Total => Volatile.Read(ref s_Total);
}
推荐阅读
- c - 我无法使用链表打印多项式表达式
- javascript - 使我的函数更可重用的提示
- sql-server - SQL 登录已创建但未映射 - 用户已存在 - 之间是否有任何联系?
- ios - 如何快速获取集合视图的当前索引路径
- pytorch - 从列表而不是文件创建 SequenceTaggingDataset
- python - OpenCv错误无法通过视频捕获打开相机
- javascript - 如何使用 Firebase 上传多个文件?
- c# - 有没有办法像这样过滤 C# DataView?
- c++ - CV_HAAR_SCALE_IMAGE 未在 Windows 上的 OpenCv4 中定义
- autohotkey - 从 Windows 托盘打开程序