例如,如果我无论如何注定每秒分配100Mb内存几乎立即变得无用,那么如果以500kb或500b的块分配,它会更快吗?
更大的块可能会进入大对象堆 - 这会降低性能吗?
答案 0 :(得分:3)
绝对避免大对象堆 - 这意味着超过85000字节。
更新以解释一些事情并回答您的评论
我的直觉说要去寻找最大的对象大小,仍然可以避免大对象堆。原因与其他答案相同 - 较少的对象表面上意味着简单,较短的收集周期。我想避免LOH的原因是因为长时间运行程序的压缩问题。如果您使用并从LOH每秒丢弃100MB,那么距您的程序崩溃只有大约21秒。原因是收集了LOH,但从未压实过。内存被回收并可供操作系统提供给其他程序,但您的进程的地址空间仍然被锁定。 100MB / s * 21s将填满您的进程可用的2GB地址空间。那时,你遇到了OutOfMemoryException。
此外,我希望你除了垃圾收集的时间百分比之外还使用其他措施。处理100MB / s,你必须习惯那里的高数字。在这种情况下,降低并不总是更好。想象一下,你有一个运行80%垃圾收集的程序,并在5分钟内完成。这是垃圾收集的4分钟。您添加一些代码来查看每个对象并将其分解或构建新对象以获得更有利的GC配置文件。它似乎有用 - 比方说你的新号码是75%。但是,如果75%来自6分钟的程序运行和4.5分钟的垃圾收集,你是否真的获得了任何收益,因为代码复杂性增加了?换句话说,除非您还将该度量与总处理时间配对,否则请勿在垃圾回收中使用百分比。也就是说,超过50%的人看起来对我很怀疑,所以我认为你确实有一些改进空间。
答案 1 :(得分:1)
我的直觉让我觉得LOH会更快,因为LOH的管理明显更直接,即没有世代,没有扫描和没有压缩(85k或85k以上的物体进入LOH)。你与LOH的真正敌人是没有压缩,因此碎片可能是一个问题,但是如果你分配的是相同大小的短暂对象,这应该可以减少碎片化的可能性。
然而,直觉是一回事,现实是另一回事。与大多数性能问题一样:
Don't think, measure.
重新使用内存的方案可能是更好的解决方案。
答案 2 :(得分:1)
GC做了一些事情
1.查找所有活动对象
2.压缩活动对象使用的内存
更少的活动对象意味着找到它们会更快。 大型对象是从未在所有集合上压缩的特殊堆中分配的,因此它会更快。
理论上,较少的大型物体可以加快GC的速度。如果这会影响整个应用程序的性能,则需要测量。我会首先编写最易维护的代码,看看性能是否有问题。
答案 3 :(得分:1)
GC工作量不是基于对象总数,而是基于可达对象的数量(确定每个集合的工作量)和分配率(确定集合数)。
假设以字节/秒为单位的分配率相同,短期对象的大小不应对GC工作产生太大影响。
例外是具有终结器的对象。 (严格来说,这些并不是短暂的。)从具有终结器的对象可以访问的对象也非常糟糕。您可能需要拆分一些类并将可终结的东西放入成员子对象(而不是基类)中,这样只有终结器使用的字段才是可终结子对象的一部分,并且复合对象的其余部分可以立即释放