Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.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
Vb.net 具有通用堆栈的垃圾收集_Vb.net_Silverlight 4.0_Garbage Collection - Fatal编程技术网

Vb.net 具有通用堆栈的垃圾收集

Vb.net 具有通用堆栈的垃圾收集,vb.net,silverlight-4.0,garbage-collection,Vb.net,Silverlight 4.0,Garbage Collection,我正在为Silverlight中的自定义文本框控件编写一个多撤消/重做系统。我现在正在做的是减少内存消耗 所以我遇到的问题是,我使用的堆栈在内存中保存的时间太长 我认为只要堆栈的计数自然达到0,或者堆栈由于事件而被清除,那么完全擦除堆栈的成本相对较低。所以我正试图用这段代码来实现这一点,希望GC能够接收到这一点 TextHistory.Clear() TextHistory = Nothing 但这肯定不起作用,而且这个堆栈可能容纳50MB或更多。顺便说一下,TextHistory是一个堆栈(

我正在为Silverlight中的自定义文本框控件编写一个多撤消/重做系统。我现在正在做的是减少内存消耗

所以我遇到的问题是,我使用的堆栈在内存中保存的时间太长

我认为只要堆栈的
计数自然达到0,或者堆栈由于事件而被清除,那么完全擦除堆栈的成本相对较低。所以我正试图用这段代码来实现这一点,希望GC能够接收到这一点

TextHistory.Clear()
TextHistory = Nothing
但这肯定不起作用,而且这个堆栈可能容纳50MB或更多。顺便说一下,
TextHistory
是一个
堆栈(瞬间)
。现在是
时刻
课程

Public Class Moment
    Public Text As String
    Public SelectionStart As Integer
    Public SelectionLength As Integer

    Public Sub New(ByRef _Text As String, _SelectionStart As Integer, _SelectionLength As Integer)
        Text = _Text
        SelectionStart = _SelectionStart
        SelectionLength = _SelectionLength
    End Sub 
End Class
堆栈(Of T)是使用T数组实现的。该阵列的容量为50MB,在仅使用gen 2收集的大型对象堆上被复制和增长了很多次。大型对象堆也不会被压缩,因此如果为数组副本分配了额外的空间,那么在GC收集数组后,该空间将保持分配状态,但剩余的“洞”将可用于其他对象

如果您的堆栈确实需要增长这么大,您可以通过一个链表实现您自己的堆栈来绕过使用大型对象堆的问题。

堆栈(Of T)是使用T数组实现的。该阵列的容量为50MB,在仅使用gen 2收集的大型对象堆上被复制和增长了很多次。大型对象堆也不会被压缩,因此如果为数组副本分配了额外的空间,那么在GC收集数组后,该空间将保持分配状态,但剩余的“洞”将可用于其他对象


如果您的堆栈确实需要增长这么大,您可以通过一个链表实现您自己的堆栈,从而绕过使用大型对象堆的问题。

在您的评论中,您说强制GC起作用(works=清理垃圾)。这就是它的工作原理

GC根据需要进行。需求是大量分配、内存压力或手动触发。这些都没有发生,这就是为什么垃圾没有得到清理


GC不会基于时间(比如每分钟左右)运行。

在您的评论中,强制GC起作用(works=清理垃圾)。这就是它的工作原理

GC根据需要进行。需求是大量分配、内存压力或手动触发。这些都没有发生,这就是为什么垃圾没有得到清理



GC不会以时间为基础(比如每分钟左右)运行。

这会起作用。有一些您没有告诉我们的事情导致了问题。你知道GC不会立即发生吗?我相信可以安全地假设你没有持有对TextHistory堆栈或其他任何时刻对象的引用?@usr-我知道GC不会立即发生,但我正在查看GC.GetTotalMemory()和整个Silverlight进程的实际内存使用情况,他们将所有这些记忆保留了好几分钟(可能永远)。然后我注释掉了推到TextHistory堆栈上的那行,当执行相同的任务时,内存使用只增加了2或3 MB(而不是50 MB)。@roken-我不知道。你强制GC了吗?GC不会基于时间发生。等待无助于触发它。这会起作用。有一些您没有告诉我们的事情导致了问题。你知道GC不会立即发生吗?我相信可以安全地假设你没有持有对TextHistory堆栈或其他任何时刻对象的引用?@usr-我知道GC不会立即发生,但我正在查看GC.GetTotalMemory()和整个Silverlight进程的实际内存使用情况,他们将所有这些记忆保留了好几分钟(可能永远)。然后我注释掉了推到TextHistory堆栈上的那行,当执行相同的任务时,内存使用只增加了2或3 MB(而不是50 MB)。@roken-我不知道。你强制GC了吗?GC不会基于时间发生。等待无助于触发它。那么你是说,如果我让撤销系统在存储内容方面更有效(我正在处理它),那么垃圾收集器将因此更好地处理这个问题?现在它的效率非常低,因为它存储的是整个
文本
值,可以说代表了历史中的整个快照。我将把它改为只存储
SelectedText
值,这将大大减少内存消耗。@SteveWortham这将有所帮助,因为我猜如果堆栈增长到50MB,会有大量的时间(顺便问一下,你是如何得到这个数字的?)。最好的办法是使用内存分析器来获得内存使用情况的真实图像。你可以免费试用红门蚂蚁,这是一个很好的工具(IMO)。@SteveWortham还值得注意的是,力矩对象引用的字符串大小不会出现在我的答案中的解释中,因为字符串本身并不作为力矩对象的一部分存在于LOH上,为了得到这个数字,我比较了使用和不使用TextHistory堆栈时的内存使用情况,同时在应用程序中执行相同的任务。我使用
GC.GetTotalMemory(False)
函数获取内存使用情况。在我的测试中,我使用了一个超过100KB的字符串,你把它乘以它的所有历史,你就得到了一个大字符串。但实际上是字符串的大小比其他任何因素都重要。@SteveWortham啊,那么是的,那些巨大的字符串最终会出现在LOH上,很可能是你的罪犯。那么你是说如果我让撤销系统在存储内容方面更有效(我正在处理它),那么垃圾收集器会因此更好地处理这个问题吗?太可怕了