简体   繁体   English

内存碎片?

[英]Memory fragmentation?

I'm not sure because I don't have much experience in analysing memory dumps, but I think we may have problems with memory fragmentation. 我不确定,因为我在分析内存转储方面没有太多经验,但我认为我们可能会遇到内存碎片问题。

During load tests we see that memory usage is growing to the point where application restarts. 在负载测试期间,我们看到内存使用量正在增长到应用程序重新启动的程度。 It is ASP.NET MVC 4 app on 64 bit machine. 它是64位机器上的ASP.NET MVC 4应用程序。 I wasn't involved in writing it. 我没有参与写作。 I was just asked to try to analyze memory dumps. 我被要求尝试分析内存转储。

So during last load test we created 3 memory dumps (below their sizes and total GC Heap size output from eeheap -gc): 因此,在上次加载测试期间,我们创建了3个内存转储(低于它们的大小和来自eeheap -gc的总GC堆大小输出):

  1. 1.70GB, 292MB 1.70GB,292MB
  2. 2.03GB, 337MB 2.03GB,337MB
  3. 2.55GB, 347MB 2.55GB,347MB

So as you see managed heap isn't growing as much as dump files. 因此,您看到托管堆的增长速度不如转储文件。 When I do dumpheap -stat I see most space is used by Free objects (below for each dump file) 当我执行dumpheap -stat时,我发现Free对象使用了大部分空间(下面是每个转储文件)

  1. 147MB 147MB
  2. 145MB 145MB
  3. 213MB 213MB
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
000000bcc668e0a8    0.7MB 000000bcc6738650 System.Object[]
000000bcc6949f88    4.4MB 000000bcc6dab820 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
000000bd4626c4b8    0.7MB 000000bd463165f8 System.Byte[]
000000bd463fcc48   51.5MB 000000bd4977baf0 System.Threading.ThreadStart
000000be463600c8    0.7MB 000000be464108f0 Free
000000bec67e50e0    1.1MB 000000bec690b020 System.Collections.Generic.List`1[[OurType, ANotherOurType]]
000000bec690b0b8    3.2MB 000000bec6c3b170 System.Byte[]
000000bfc6605e00    1.0MB 000000bfc6710190 Free
000000bfc6743c58   32.8MB 000000bfc8806fe8 System.Threading.ExecutionContext
000000c046200580    1.0MB 000000c0462ff2a0 SomeOurType
000000c0463a1270    3.6MB 000000c046732ac0 Microsoft.Win32.SafeHandles.SafeCapiKeyHandle

From what I understand it is not problem when Free objects are only small fraction of total amount of memory in all heap sizes. 根据我的理解,当Free对象只是所有堆大小的总内存量的一小部分时,这不是问题。 Here looks like it is a problem. 这看起来像是一个问题。

App is using two external libraries. App正在使用两个外部库。 One for creating PDF-s and other for creating Barcode files. 一个用于创建PDF-s和其他用于创建条形码文件。 Barcode library is throwing AccessViolationException (about 70 times for 2200 attempts). 条形码库抛出了AccessViolationException(2200次尝试大约70次)。 It throws with this stacktrace 它抛出了这个堆栈跟踪

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Drawing.SafeNativeMethods.Gdip.IntGdipDeleteGraphics(HandleRef graphics)
   at System.Drawing.Graphics.Dispose(Boolean disposing)
   at System.Drawing.Graphics.Dispose()
   at Lesnikowski.Barcode.BaseBarcode.Render()
   at Lesnikowski.Barcode.BaseBarcode.Save(Stream stream, ImageType imageType)

I've read that memory fragmentation is often caused by pinning memory, but this is !gchandles output 我已经读过内存碎片通常是由固定内存引起的,但这是!gchandles输出

Handles:
    Strong Handles:       154
    Pinned Handles:       23
    Ref Count Handles:    2
    Weak Long Handles:    1794
    Weak Short Handles:   74
    SizedRef Handles:     17
    Dependent Handles:    1

I don't know what else I can check. 我不知道还能检查什么。 Do we have memory fragmentation problem? 我们有内存碎片问题吗? Can you point me in some direction? 你能指点我吗?

Edit: I attach performance counters collected during load test. 编辑:我附加在负载测试期间收集的性能计数器。 Weird because it's showing a lot of pinned objects but !gchandles didn't show them. 奇怪,因为它显示了很多固定的对象但是!gchandles没有显示它们。

在此输入图像描述

red line   - user load
green line - bytes in all heaps
blue line  - pinned objects

Edit2: Added Fragmented blocks larger than 0.5 MB: output from !dumpheap -stat Edit2:添加大于0.5 MB的碎片块:从!dumpheap -stat输出

You should use !address -summary to get an idea of the virtual memory usage in this process. 您应该使用!address -summary来了解此过程中的虚拟内存使用情况。 Even though there seems to be some heap fragmentation, there is very likely some additional heavy memory consumer in your process. 尽管似乎存在一些堆碎片,但在您的过程中很可能会有一些额外的大量内存使用者。 It could be the Win32 heap, it could be thread stacks, it could be assemblies you are loading dynamically, and so on. 它可能是Win32堆,它可能是线程堆栈,它可能是您正在动态加载的程序集,依此类推。

For each type of leak you would then have to follow a slightly different approach. 对于每种类型的泄漏,您必须遵循稍微不同的方法。 For Win32 heap inspection, you should use variations of the !heap command - !heap -stat , !heap -s -h 0 . 对于Win32堆检查,您应该使用!heap命令的变体 - !heap -stat!heap -s -h 0 For assembly loading issues, you should look at the loader heap with !eeheap -loader and then inspect the various AppDomains you have with !dumpdomain to see which assemblies you are loading. 对于程序集加载问题,您应该使用!eeheap -loader查看加载程序堆,然后检查您使用的各种AppDomain !dumpdomain以查看要加载的程序集。 These are just some examples - you will have to provide more details about your situation. 这些只是一些例子 - 您必须提供有关您的情况的更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM