分配相同大小的对象会改善GC还是“new”?表演
本文关键字:还是 GC new 表演 对象 分配 | 更新日期: 2023-09-27 18:18:57
假设我们必须创建许多字节数组类型的小对象。大小不同,但总是小于1024字节,例如780,256,953....
如果我们总是只分配字节[1024],并且只使用所需的空间,它会随着时间的推移提高操作符new或GC效率吗?
UPD:这是为解析二进制协议消息而创建的短活对象。
UPD:在两种情况下,对象的数量是相同的,只是分配的大小发生了变化(随机vs.总是1024)。
在c++中,这很重要,因为碎片和c++的新性能。但是在c#中....
如果我们总是只分配字节[1024],并且只使用所需的空间,它会随着时间的推移提高操作符new或GC效率吗?
也许。你必须对它进行剖析,然后看看。
我们在Roslyn编译器中分配语法树节点的方式非常有趣,我最终会写一篇关于它的博文。在那之前,与你的问题相关的部分是这一点有趣的琐事。我们的分配模式通常涉及分配一个"底层"不可变节点(我们称之为"绿色"节点)和一个包装它的"外观"可变节点(我们称之为"红色"节点)。正如你想象的那样,我们经常会成对地分配它们:绿色、红色、绿色、红色、绿色、红色。
绿色节点是持久的,因此寿命长;外观是短暂的,因为它们在每次编辑时都会被丢弃。因此,经常出现垃圾收集器有绿/孔/绿/孔/绿/孔,然后绿节点上移一代的情况。
我们的假设一直是使数据结构更小总是会提高GC性能。更小的结构等于更少的内存分配,等于更少的收集压力,等于更少的收集,等于更高的性能,对吧?但是我们通过分析发现,在这个场景中使红节点变小实际上降低了 GC性能。特定大小的洞以某种奇怪的方式影响GC ;我不是垃圾回收器内部的专家,我不明白为什么会这样。
那么是否有可能改变分配的大小会以某种不可预见的方式影响GC ?是的,这是可能的。但是,首先,不太可能,其次,除非您在实际场景中实际尝试并仔细测量GC性能,否则不可能知道您是否处于这种情况。 当然,您可能不会对GC性能进行限制。Roslyn做了很多小的分配,这对我们调整gc影响行为至关重要,但我们做了一个疯狂的小分配。绝大多数。net程序不像我们这样强调GC。如果你是少数以有趣的方式强调GC的程序中的一员,那么就没有办法绕过它;你需要做侧写并收集经验数据,就像我们在罗斯林团队所做的那样。 如果你不是少数,那么不要担心GC性能;你可能在其他地方有更大的问题需要先处理。
new
是快速的,是GC导致了问题。因此,这取决于数组的寿命。
如果它们只存在很短的时间,我认为分配1024字节数组不会有任何改善。实际上,由于浪费空间,这将给GC带来更大的压力,并且可能会降低性能。
如果它们在应用程序的生命周期中存在,我会考虑分配一个大数组,并为每个小数组使用它的块。您需要对它进行分析,看看它是否有帮助。
不是真的,分配或清除字节数组只需要一条指令,而不管它的大小。我说的是你的情况。也有例外)
你不应该担心垃圾收集的性能方面,除非你确定它是你的应用程序的瓶颈(例如,你创建了许多具有复杂关系的引用,并在不久之后抛出它……)垃圾收集是显而易见的。)
要阅读一个关于一个著名的(并且非常有用的)站点在。net GC中出现性能问题(在一个令人印象深刻的用例中)的优秀故事,请参阅这个博客。http://samsaffron.com/archive/2011/10/28/in-managed-code-we-trust-our-recent-battles-with-the-net-garbage-collector;)
但是关于GC最重要的事情是:永远不要在确定存在问题之前进行优化。因为如果你这样做了,你可能会有一个。应用程序是复杂的,并且GC在运行时与它的每个部分进行交互。除了简单的情况外,提前预测其行为和瓶颈(在我看来)似乎很困难。
我也不认为只分配1024字节数组会改善GC。由于GC是不是确定性的,我也认为这不会是你的问题。
您可以通过在数组周围使用using {}
语句来影响GC,以便(可能)更快地释放内存。
我不认为GC会是问题和/或瓶颈。
分配不同大小的对象并以不同的顺序释放它们可能导致堆内存碎片化。这就是分配相同大小的对象可能会派上用场的地方。
如果你确实需要分配/释放很多,并且确实认为这是你的瓶颈,尝试使用本地对象缓存来重用对象。这可以提高性能,特别是如果它们是仅用于数据的对象,没有实现大量逻辑。如果对象确实实现了大量的逻辑,并且需要更复杂的初始化(raii模式),我会为了程序的健壮性而放弃性能的提高……
hth
马里奥