Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-在终结器中回收资源的缺点_C#_Garbage Collection_Finalizer_Recycle - Fatal编程技术网

C#-在终结器中回收资源的缺点

C#-在终结器中回收资源的缺点,c#,garbage-collection,finalizer,recycle,C#,Garbage Collection,Finalizer,Recycle,正如标题所述:在包含对象的终结器中回收资源(如大型数组)是否有任何不利之处?到目前为止,它工作得很好,但由于终结器可能有点时髦,并且难以调试,所以我决定在这里询问 用例是一个多边形类,它只表示一个点列表。我的应用程序大量使用了具有几千个点的大型多边形——分配这些数组通常并不便宜。不幸的是,dispose模式是不可能的,因为它们会被传递,并且几乎只有GC知道何时没有其他对象引用它们 我就是这样实现的(数组的长度总是2^sizelo2,只有sizelo2>=MIN\u SIZE\u LOG\u 2的

正如标题所述:在包含对象的终结器中回收资源(如大型数组)是否有任何不利之处?到目前为止,它工作得很好,但由于终结器可能有点时髦,并且难以调试,所以我决定在这里询问

用例是一个多边形类,它只表示一个点列表。我的应用程序大量使用了具有几千个点的大型多边形——分配这些数组通常并不便宜。不幸的是,dispose模式是不可能的,因为它们会被传递,并且几乎只有GC知道何时没有其他对象引用它们

我就是这样实现的(数组的长度总是
2^sizelo2
,只有
sizelo2>=MIN\u SIZE\u LOG\u 2
的数组才能回收):

建造商:

公共多边形(整数容量=1)
{
//求整数对数上限的快速方法
int sizeLog2=UIM.CeilingLog2((uint)容量);
//Suppress finalize何时不应回收阵列
如果(sizeLog2<两个功率最小值)GC.SuppressFinalize(此);
点=创建(sizeLog2);
}
创建大小为2^sizeLog2的数组:

private static Pnt[]创建(int-sizeLog2)
{
如果(sizeLog2>=两个功率最小尺寸)
{
如果(/*尝试从回收队列获取项目*/)返回结果;

Pnt[]points=new Pnt[1简短的回答是有。大型数组不是终结器打算回收的资源类型。终结器应该用于外部资源,并且在应用程序状态的罕见情况下使用

我建议写一篇文章和/或这篇文章,以便更好地理解定稿中的一些陷阱

您所描述的问题的关键是这样一句话:“我真的不能让GC完成所有的工作,因为在几秒钟内我就在大型对象堆上拥有数百MB的内存。”

但是,在GC“完成所有工作”之前,永远不会调用终结器,因此您不能完全理解是什么导致了应用程序的内存压力


听起来你对你的应用程序的整体设计有问题,你发现很难对谁拥有多边形和/或PNT进行推理。结果是,当你不希望拥有多边形和/或PNT时,在某个地方会有对多边形/PNT的引用。使用一个好的分析器来找出发生这种情况的地方,并修复这个整体设计问题问题是尝试使用终结。

GC.KeepAlive
对初学者来说不起作用。我不太确定你想在这里实现什么-
Recycle
做什么?为什么
null
事后对
点进行终止?看起来你在试图重新发明
ArrayPool
@Damien\u不信者好的谢谢你,我的亲戚当然,很明显,这种方法仍然有效的原因是数组在终结器中被重新激活。@KonradKokosa Yes recycle做的与ArrayTool做的差不多,确切地说:
RecycleQueue[UIM.BitPosition(points.Length)-MIN\u SIZE\u LOG\u 2]。Add(points)
所以它是一个单行程序,我可以更好地控制到底发生了什么,这就是为什么我没有首先使用ArrayPool。然而,这完全是离题的,问题是,在终结器中回收一个对象并使用ArrayPool或不使用ArrayPool时,是否存在我没有想到的任何不利因素或风险不会有什么不同关于这一点,我不确定在终结器的上下文中,您可以在Recycle内部执行哪些有用的操作。终结器被设计为允许处理外部资源。作为一般规则,它们不应该访问托管对象。我意识到终结器不应该用于此目的,IDisposable接口将LD解决了这个问题,但缺点是,处理多边形的用户代码必须处理对象,如果我在C++中编程,这将是完全好的,但是C.I有一个GC,我的应用程序是用来利用它的,GC还没有完成所有的工作,在TH中分配大量的对象有巨大的成本。e LOH这正是回收所阻止的。@NiklasHauber IDisposable可能也不能解决这个问题。我建议您看看ArrayPool或MemoryPool。听起来您真正想要的是一种重用大量PNT的方法。我自己也在做回收工作,与ArrayPool类似,但它是一个非常精简的版本,t这就是回收方法的作用。我没有包括实现,但调用旁边的注释解释了它的作用。在谷歌搜索了一段时间后,我甚至找到了一个术语来描述我正在做的事情,这就是对象复活。因此,这不完全是一个漂亮的编程,但这样做似乎是安全的,也很方便。IDisposable只能解决非确定性终结的问题,但在这种情况下这不是一个要求。@NiklasHauber我关于IDisposable的观点是,虽然它在添加确定性清理时确实有用,但管理您正在使用的大型对象这一更大的问题是一个约束,需要一些更高级别的设计工作o解决。例如,任何拥有多边形的人都可能需要负责管理内存。如果明确定义了这些责任,则不需要终结器或对象恢复。不能真正定义谁拥有多边形,它们应该是可以由任何其他项目自由使用的类型。因此,我要么做一些丑陋的pr像我一样编程,接受了巨大的性能损失,或者增加了使用这些多边形的代码的复杂性,迫使它手动管理内存以提高性能,而编程语言的设计方式是程序员不必这样做的。我甚至不能得到C语言中类似于共享_指针的东西#.