首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为漏泄的应用程序创建性能分析器输出?

为漏泄的应用程序创建性能分析器输出?
EN

Stack Overflow用户
提问于 2020-05-11 19:32:06
回答 1查看 79关注 0票数 3

我正在寻找.NET项目中的内存和资源泄漏,因为应用程序最终会崩溃,出现一些普通的GDI+异常,有时还会出现OOM错误。我正在分析的库使用了System.Graphics API,但没有直接指向GUI。我正在使用VisualStudio2019企业版和内置性能分析器工具来分析内存使用情况。该工具是用来捕获托管和本机堆使用情况的。我拍了两张照片。第一个是库尚未被调用时的基线。第二个快照是在循环中重复调用库方法并最终调用GC.Collect()GC.WaitForPendingFinalizers()之后。下面是内存使用图的截图。第一个显示托管堆,第二个显示本机堆。

事件探查器显示托管堆的输出

Profiler输出显示本机堆

进程资源管理器在据称泄漏后的条目

分析WinDbg中的内存转储

代码语言:javascript
复制
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free                                    891     7ffd`bb247000 ( 127.991 TB)           99.99%
<unknown>                               916        2`3b96d000 (   8.931 GB)  98.40%    0.01%
Image                                   471        0`0837e000 ( 131.492 MB)   1.41%    0.00%
Heap                                     35        0`007e4000 (   7.891 MB)   0.08%    0.00%
Stack                                    21        0`00700000 (   7.000 MB)   0.08%    0.00%
Other                                     8        0`001cb000 (   1.793 MB)   0.02%    0.00%
TEB                                       7        0`0000e000 (  56.000 kB)   0.00%    0.00%
PEB                                       1        0`00001000 (   4.000 kB)   0.00%    0.00%

--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE                             944        2`395e9000 (   8.896 GB)  98.02%    0.01%
MEM_IMAGE                               491        0`08a1a000 ( 138.102 MB)   1.49%    0.00%
MEM_MAPPED                               24        0`02da6000 (  45.648 MB)   0.49%    0.00%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE                                891     7ffd`bb247000 ( 127.991 TB)           99.99%
MEM_COMMIT                             1379        1`287f4000 (   4.633 GB)  51.05%    0.00%
MEM_RESERVE                              80        1`1c5b5000 (   4.443 GB)  48.95%    0.00%

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READWRITE                         1010        1`1e71f000 (   4.476 GB)  49.31%    0.00%
PAGE_EXECUTE_READ                        52        0`05ec3000 (  94.762 MB)   1.02%    0.00%
PAGE_READONLY                           180        0`032ca000 (  50.789 MB)   0.55%    0.00%
PAGE_WRITECOPY                          113        0`00ed6000 (  14.836 MB)   0.16%    0.00%
PAGE_EXECUTE_READWRITE                   17        0`00051000 ( 324.000 kB)   0.00%    0.00%
PAGE_READWRITE|PAGE_GUARD                 7        0`00021000 ( 132.000 kB)   0.00%    0.00%

--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free                                      1`3dbe9000     7ff2`c85d7000 ( 127.948 TB)
<unknown>                              7ff4`06370000        1`00020000 (   4.000 GB)
Image                                  7ffd`63eba000        0`0103d000 (  16.238 MB)
Heap                                      0`1ded2000        0`0017d000 (   1.488 MB)
Stack                                     0`1bac0000        0`000fa000 (1000.000 kB)
Other                                     0`017d0000        0`00181000 (   1.504 MB)
TEB                                       0`00e0d000        0`00002000 (   8.000 kB)
PEB                                       0`00e0c000        0`00001000 (   4.000 kB)

令我费解的是,图中的内存使用量(私有字节)一直在增长(高达5GB),但是快照#2只显示了大约2.55MB的本地堆和大约316 KB的托管堆使用情况。实际上,这个库函数被调用了大约400次,只是为了加剧这个问题。私有字节的使用与循环计数成正比。尽管每次迭代之后,库方法返回的对象都会被释放,但是内存使用永远不会达到稳定状态,并且如果循环计数增加,则会不断增加。这一点以及最终的GDI+异常对我来说意味着库正在泄漏句柄或内存,但分析器输出似乎没有表明这一点。如果有人能对这件事有所了解并帮助我理解我在这里看到的,我会很高兴的。

EN

回答 1

Stack Overflow用户

发布于 2020-05-14 15:13:08

正如@ThomasWeller所指出的,这最终是图像数据的泄露。我想我会在这里发表我的发现作为答案,希望它能对某人有所帮助。

在与WinDbg度过了一段时间之后,我仍然找不到任何帮助我解决这个漏洞的东西,这可能是因为我在使用这个工具方面缺乏专业知识。然后,我遇到了一个使用来自SysInternals的SysInternals实用工具的建议。我发现这很容易使用,但显然没有WinDbg那么强大。下面显示的是泄漏发生后VMMap的屏幕截图。

可以看到,堆的使用率仅为8MB,而私有数据的使用率约为9GB。单击“私有数据条目”显示数百个相同大小的分配条目。鉴于图书馆的性质,这表明它是某种图像数据。我的第一个怀疑是位图对象没有被处理,但是查看代码中位图的每一次使用都没有发现任何东西。然而,在看这个时,我发现了一个对Bitmap.LockBits的调用,它没有相应的UnlockBits调用。事实证明这是泄漏的原因。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61737804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档