c# - 什么是 GC 漏洞?

标签 c# .net memory-leaks garbage-collection

<分区>

我用C#写了一个长TCP连接套接字服务器。我的服务器内存中出现峰值。我使用 dotNet Memory Profiler(一种工具)来检测内存泄漏的位置。 Memory Profiler 显示private heap 很大,内存如下图(数字不是真实的,我想展示的是GC0 和GC2 的Holes 非常非常大,数据大小正常):

  Managed heaps - 1,500,000KB 
          Normal heap - 1400,000KB 
              Generation #0 - 600,000KB 
                  Data - 100,000KB 
                  "Holes" - 500,000KB 
              Generation #1 - xxKB 
                  Data - 0KB 
                  "Holes" - xKB 
              Generation #2 - xxxxxxxxxxxxxKB 
                  Data - 100,000KB 
                  "Holes" - 700,000KB 
          Large heap - 131072KB 
              Large heap - 83KB 
              Overhead/unused - 130989KB 
          Overhead - 0KB

然而,什么是GC hole? dotNet Memory Profiler 的文档确定了“漏洞”:

“Holes” represent memory that is unused between two allocated instances. “Holes” appear when the heap is not fully compacted, due to pinned instances or optimizations in the garbage collector.

我想知道的是:

  1. 哪种类型的两个分配实例之间出现“洞”?
  2. 固定了哪些实例?
  3. 如何压缩堆?

希望有人能解释一下。

最佳答案

A pinned object是不允许在内存中移动的。在使用非托管代码时通常需要这样做,这需要您传入指向内存中某个结构的指针 - 默认情况下,垃圾收集器可以自由移动该结构以便最好地管理内存,但是如果它在您这样做时这样做'已经为一些非托管代码提供了指向该结构的指针,那么如果它移动了,那么非托管代码将不再指向正确的结构,从而导致意外行为。

解决方案是“固定”该对象以告诉 GC 它不应该移动它。

您不能显式压缩堆,GC 应该在执行完整或部分收集时自行压缩堆(LOH 除外)- 固定大量对象将使其更难成功管理这不过。有关 GC 的更多详细信息,请参阅 Garbage Collector Basics and Performance Hints

关于c# - 什么是 GC 漏洞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12892298/

相关文章:

c# - 在 C# 中完成方法指南和最佳实践

c# - zlib.c Adler 实现和 Deflate、Ionic Deflate 之间的 Zlib 压缩差异

c# - 使用 AppDomain.CreateInstanceAndUnwrap 方法时为 "Unable to cast transparent proxy to type"

c# - Winforms应用程序如何回调上一个窗体?

ios - 使用 Xcode Instruments 从内存地址打印对象

jakarta-ee - Java EE 对象监控工具

c# - 即使使用值 Entity Framework ,实体属性也为空

c# - 右键单击文件以使用 .NET 程序打开它

c# - string.GetHashCode 和 IEqualityComparer<string>.Default.GetHashCode 之间的区别

c++ - 检测到内存泄漏