我有x86 WPF应用程序,应用程序显示了大量来自RabbitMQ的实时流数据。应用程序以大约500 MB的内存启动,但在白天,由于用户加载的数据越来越多,它可能会增加到900到1000 MB。一旦达到900 MB左右,阈值应用程序就会变得非常慢,响应速度也不会那么快。例如,编辑DevExpress网格需要时间(我必须承认,每次修改都会触发大量活动,但当内存低于900 of时,就会很好)。用户拥有高规格的计算机(i7 CPU,128Gb内存),有大量的免费资源。
我们诊断了内存泄漏、CPU使用情况下的应用程序,一切正常。由于加载了更多的数据,预计将从500 to增长到900 to。据我所知,x86被限制在2GB以内,但对我来说,应用程序很慢(+在900 MB左右开始抛出内存异常)。我们该怎么办?需要检查什么?
发布于 2022-10-21 14:40:50
如果可以的话,切换到x64。到目前为止,没有什么理由使用32位代码,除非您正在使用一些真正古老的库。
它还取决于您正在测量的内容,即整个进程内存,或实际使用的内存。内存分析器应该会给出稍后的内容。垃圾收集器需要比实际使用的内存稍微多一点,但是100%的开销似乎有点大。
另一个可能的原因是内存碎片。虽然小内存分配将被自动分割/压缩,更大的分配(我上次检查的85kb+)将放置在大对象堆(LOH)上,而这并不是自动压缩的。这可能导致存在大量可用内存的情况,但没有一个“洞”大到足以满足内存请求。一个好的记忆分析器应该能让你对LOH碎裂的程度有一些了解。另见Windows系统上的大型对象堆
通过运行,可以手动压缩LOH。
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();但这有点像绷带。迁移到x64会更好,使用某种类型的内存池来分配固定大小的块以避免碎片化可能是最好的。
经验法则是,当分配量很小且寿命很短时,或者在整个应用程序生命期内保持活动状态时,.Net的工作效果最好。前者将由gen2 0/1(即fast)集合处理,后者放置在gen2 2/LOH中,从未收集。对于垃圾收集器/内存分配器来说,高频、大、可变大小的分配可能是最坏的情况。
https://stackoverflow.com/questions/74155083
复制相似问题