我们的一种产品在生产时消耗 GB 内存,这是一个长期问题。我们经常在服务器上收到内存不足的警告,今天终于有机会坐下来用内存分析器看看内存的去向。在开发中,使用相同的数据库和配置,应用程序的私有工作集为 450MB。在生产服务器上,分配给该进程的内存量为 3.7GB。
使用 Ants Memory Profiler,我确定将 2.906GB 的内存分配给第 1 代堆:
当我们从数据库加载大量数据以生成一些缓存时,这个内存量确实会在应用程序启动时得到利用。但是,这一切都被清理了,正如您可以看到上图中的所有数据都已分配但未使用的事实。这是完整的概述:
如您所见,LOH 几乎是空的,没有碎片化。我知道 LOH 不会被压缩,除非您专门将 CompactOnce 设置为适用的 GCSettings 枚举。但我的印象是 0-2 代堆确实被压缩了,应该释放空闲空间吗?或者 CLR 是否只是假设因为曾经消耗了这么多内存,应用程序应该继续寻址该内存以防它再次需要那么多内存?
对我来说,我们的应用程序应该只消耗大约 600-700MB(其中大部分是 CLR)。所以:
- 有谁知道为什么这个可用空间仍然被分配并且只在生产服务器上而不是在开发笔记本电脑上?
- 有没有办法从第 1 代堆中手动释放这个空闲内存?