我在C#中编写了一个长TCP连接套接字服务器。我的服务器内存中出现峰值。我使用dotNet Memory Profiler(一种工具)来检测内存泄漏的位置。内存分析器指示私有堆很大,内存类似于下面(数字不是真实的,我要显示的是GC0和GC2的孔非常大,数据大小正常):
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
Howerver,什么是GC漏洞? dotNet Memory Profiler的文档确定了“漏洞”:
“Holes”表示两个分配之间未使用的内存 实例。当堆未完全压缩时,会出现“孔” 固定垃圾收集器中的实例或优化。
我想知道的是:
我希望有人可以解释一下。
答案 0 :(得分:5)
pinned object是不允许在内存中移动的LOH。在处理非托管代码时经常需要这样做,这需要您将指针传递给内存中的某个结构 - 默认情况下,垃圾收集器可以自由移动该结构以便最好地管理内存,但是如果它在您执行时执行此操作我给了一些非托管代码一个指向该结构的指针,然后如果它被移动,那么非托管代码将不再指向正确的结构,从而导致意外行为。
解决方案是“固定”该对象,告诉GC它不应该移动它。
你不能明确地压缩堆,GC在执行完全或部分收集时应该这样做(Garbage Collector Basics and Performance Hints除外) - 固定大量对象会使它更难但是成功地管理了这个有关GC的更多详细信息,请参阅{{3}}