为什么要“查看堆"?结果与Visual Studio中的“进程内存使用情况"不匹配 [英] Why the "View Heap" result does not match with 'Process Memory Usage' in Visual Studio

查看:493
本文介绍了为什么要“查看堆"?结果与Visual Studio中的“进程内存使用情况"不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Visual Studio跟踪我的应用程序中的内存使用情况.在诊断工具"窗口中,它显示我的应用程序正在使用423 MB.谢谢我转到内存使用"和"ViewHeap",当我单击快照时,我得到了一个对象大小的表.

但是当我将这些数字加起来时:

= 3317228 
+  403764
+  354832
+  264984
+  244836
+  195748
+  144032
+   28840
+   16452
+   13920
+   13888
+    3428
+    2100
+      20
= 5004072
= 4.77 MB

我的问题是,为什么这个数字4.77MB与我在内存"图表上看到的423MB不匹配.我希望看到左边的表格有423 MB的细分.请告诉我我想念什么?

解决方案

为什么查看堆"大小与内存图表大小不匹配?

可能有很多原因,包括 JITter 调试工具调试符号我的代码垃圾收集等.我们将介绍其中的两个.

就是我的密码

Visual Studio的仅我的代码功能倾向于隐藏来自用户的分配,异常,断点和任何其他非代码元数据,而并非从.PDB文件或打开的项目中加载.有关详细信息,请参见 MSDN Just My Code .

调试符号和工具

在Visual Studio中调试任何项目时,Visual Studio调试器将运行并分配额外的内存以允许断点异常捕获和其它功能.对于 true 诊断工具捕获,应使用Alt+F2选项,或使用 Debug>在不进行调试的情况下启动诊断工具... .您还需要为此部分切换到发布模式.仅此步骤就将图形显示的内存(对我而言)从21.5MiB剪切为5.5MiB,表明 Debugging Symbols Debugging Tools 因素.请记住,为了使Visual Studio能够捕获异常,断点和其他数据,必须必须将其自身附加到您的流程以及流程中的所有对象.

那么,我们如何使这些数字匹配?

您真的不应该为匹配的数字担心.内存图和查看堆图的目的是让您看到峰值和奇数次的内存波动,这可能表明程序不正确.您应该寻找那些,而不是着眼于两个值之间的差异.

也就是说,您可以采取一些步骤来获得准确的结果.

完全匹配数字

如果您真正想要匹配它们,我认为无法以您希望的方式完成.但是,您可以靠近.第一步是无需调试即可启动诊断工具... ,然后选择内存使用情况.选定后,点击其旁边的设置齿轮,并确保探查器类型Mixed (Managed and Native).然后,单击开始并进行一些快照,以便您检查内存使用情况.完成后,请停止调试并检查内存.

要检查内存,请在快照框中单击要查看的快照的左上蓝色数字.在此页面上,单击右上上的网格图标,然后取消选择仅我的代码折叠小对象 >.切换到本地堆标签并执行相同的操作,取消选择仅我的代码,然后选择包括释放的分配.

您应该发现仅此一项就使您的错误更接近实际值. (实际值为 Private Bytes (私有字节),错误值为 Heap Size (堆大小).)在我测试过的应用程序中,它使(两个堆中的)总数大约为1.0265MiB,与我在Visual Studio外部运行程序时,任务管理器所指示的分配相同(此实际值为1.1211MiB,但数字很小,错误余量为预期).

包含免费分配是什么意思?本质上,当GC清除内存时,该内存不会立即从应用程序空间中删除.相反,它可以释放供其他对象使用,但可以仍保留在应用程序中. 垃圾收集是一个复杂的主题,远远超出了此问题和答案的范围.

附加说明

内存分配,使用和测量是一个非常复杂的主题.不幸的是,没有很多100%的防呆方法来处理这样的情况,并且通常,该解决方案的防呆方法越准确,越复杂,使用起来越慢且越难.

参考文献

MSDN Just My Code: https://msdn.microsoft.com/en-us/library/dn457346.aspx#BKMK__NET_Framework_Just_My_Code

MSDN垃圾回收: https://msdn.microsoft.com/en-us/library/0xy59wtx%28v=vs.110%29.aspx

此答案的其余部分基于我自己的实验试验和错误,并且可能因不同的环境而导致潜在的错误./em>此处介绍的步骤可能不适用于所有开发人员,并且是使用 Visual Studio 2015 RC 版本 14.0.22823.1 D14REL 执行的./p>

I am trying to use Visual Studio to track memory usage in my app. In the 'Diagnostic Tools' window, it shows my app is using 423 MB. Thank I go to 'Memory Usage' and 'ViewHeap', when I click on the snapshot, I get a table of the size of my objects.

But when I add those number up:

= 3317228 
+  403764
+  354832
+  264984
+  244836
+  195748
+  144032
+   28840
+   16452
+   13920
+   13888
+    3428
+    2100
+      20
= 5004072
= 4.77 MB

My question is why this number 4.77MB does not match with the 423MB I see on the "Memory" Chart. I expect to see the table on the left a breakdown of where 423 MB went. Please tell me what am I missing?

解决方案

Why does the View Heap size not match the memory chart size?

There are dozens of potential reasons for this, including JITter, Debug Tools, Debug Symbols, Just My Code, Garbage Collection et al. We'll go through two of the big ones.

Just My Code

The Just My Code feature of Visual Studio tends to hide allocations, exceptions, breakpoints, and any other non-code meta-data from the user, that was not loaded from a .PDB file or an open project. See MSDN Just My Code for details.

Debugging Symbols and Tools

When debugging any project in Visual Studio, the Visual Studio Debugger runs and allocates extra memory to allow for breakpoints, exception catching, and other features. For a true diagnostic tools capture, you should use the Alt+F2 option, or Debug > Start Diagnostic Tools Without Debugging.... You'll also want to switch to Release mode for this portion. This step alone cut the memory the graph showed (for me) from 21.5MiB to 5.5MiB, indicating that the Debugging Symbols and Debugging Tools are a substantial factor. Remember, in order for Visual Studio to be able to catch exceptions, breakpoints and other data, it must attach itself to your process, and to all objects within your process.

So, how do we make these numbers match?

You really shouldn't worry about the numbers matching. The purpose of the Memory Graph and the View Heap chart is to allow you to see spikes and odd memory fluctuations, that could indicate programme incorrectness. You should be looking for those, rather than focusing on the difference between the two values.

That said, there are some steps you can take to get accurate results.

Truly Matching the Numbers

If you truly want to match them, I don't think it can be done in the manner you wish. You can, however, get closer. The first step is to Start Diagnostic Tools Without Debugging..., then select Memory Usage. Once selected, click the Settings Gear next to it, and make sure Profiler Type is Mixed (Managed and Native). Then, click Start and take some snapshots so you can examine the memory use. Once done so, stop your debugging and examine your memory.

To examine your memory, click the top-left blue number in the snapshot box for the snapshot you wish to examine. On this page, click the Grid Icon on the top-right and deselect both Just My Code and Collapse Small Objects. Switch to the Native Heap tab and do the same, deselecting Just My Code and then select Include Freed Allocations.

You should find that this alone brings your error well closer to the actual value. (The actual value being the Private Bytes and the error being the Heap Size) With the application I tested it on, it brought the total (from both heaps) to about 1.0265MiB, which was about the same as the allocation indicated by Task Manager when I ran the programme outside of Visual Studio (this actual value was 1.1211MiB, but with numbers this small that margin of error is expected).

What does Include Freed Allocations mean? Essentially, when the GC clears memory, that memory is not immediately removed from the space of the application. Instead it is freed for use by other objects, but can still remain with the application. Garbage Collection is a complicated topic, and well beyond the scope of this question and answer.

Additional Notes

Memory allocation, usage and measurement is a very complex topic. Unfortunately, there are not many 100% fool-proof ways to handle situations like this, and generally the more fool-proof and accurate the solution is, the more complex, slow and difficult to use it is.

References

MSDN Just My Code: https://msdn.microsoft.com/en-us/library/dn457346.aspx#BKMK__NET_Framework_Just_My_Code

MSDN Garbage Collection: https://msdn.microsoft.com/en-us/library/0xy59wtx%28v=vs.110%29.aspx

The rest of this answer is based on my own experimentation and trial and error, and is subject to potential inaccuracies which may result of different environments. The steps presented herein may not work for all developers, and were performed with Visual Studio 2015 RC version 14.0.22823.1 D14REL.

这篇关于为什么要“查看堆"?结果与Visual Studio中的“进程内存使用情况"不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆