使用远程性能监视器帮助查找泄漏
我正在尝试使用远程性能监视器查找 Compact Framework 应用程序中内存泄漏的根源。我设法删除了一些与画笔和其他图形对象相关的小问题,但我仍然不清楚是什么导致了主要问题。
此时,唯一似乎永远不会返回到其原始计数的对象是 System.String 对象。我发现这很奇怪,因为我认为为了使这些对象保持未收集状态,包含它们的对象也必须保留,但似乎没有其他类型的对象随着系统.字符串。
我试图找出应用程序返回其原始状态(即登录屏幕)后保留的新 String 对象。问题在于,应用程序最初加载了大约 2200 个字符串对象,然后在进程“X”之后又增加了 70 个左右,但这些对象从未被收集。我不知道如何识别这70个新物体,以便找出谁持有它们并做出适当的更正。
有谁有过字符串未被收集的经历吗?有什么方法可以将进程“X”期间创建的新对象与应用程序最初所需的对象分开,以便我知道哪些对象正在泄漏?任何建议将不胜感激。
谢谢
**更新
好的...发生了一些非常奇怪的事情。我开始怀疑是不是漏水了。
假设我在登录屏幕上拍摄了内存快照,这是应用程序的原始起点。想象一下,此时内存中有 1000 个字符串对象。现在,如果我登录并从菜单中选择一个选项,我将在新屏幕加载后拍摄快照。假设加载此表单使字符串计数增加了 50 个对象。当我注销并在登录屏幕上再次拍摄快照时,仅收集了其中 25 个对象,其余的将从那时起保留在内存中。
奇怪的是,如果我继续重复这个过程,就不会再积累更多的字符串对象。此时字符串计数不会增加 50,而是仅添加 25 个,一旦我返回登录屏幕,将收集相同的 25 个字符串。我在想,如果这是一个实际的泄漏,那么每次我打开该屏幕时,字符串计数都会永久增加 25,但这只会发生在第一次。
在我打开的每个新屏幕上都会发生这种情况。起初,总体字符串计数会有一个小的永久性增加,但是一旦我加载了该特定屏幕,一旦我返回到登录屏幕,就会收集执行期间字符串计数的任何增加。
所有这些让我相信这些字符串也许是 CLR 内部工作的一部分或类似的东西。它可能是运行时完成的某种缓存吗?也许它正在存储我的字符串常量以加快加载速度?类似的事情?我希望这不会太令人困惑。
I'm trying to find the source of a memory leak in a Compact Framework application using the Remote Performance Monitor. I managed to remove a few minor ones related to brushes and other graphic objects, but I still don't have a clear idea of what is causing the main problem.
At this point the only objects that seem to never go back to their original count are System.String objects. I find this to be very weird, since I would've thought that in order for these objects to remain uncollected, the objects that contain them would have to remain as well, and yet no other type of objects seem to be increasing along with the System.Strings.
I'm trying to find out which new String objects are the ones that remain after the application returns to its original state (i.e. the login screen). The problem is that originally, the application loads with about 2200 string objects, and then after process "X" it increases another 70 or so which never get collected. I don't know how to identify those 70 new objects, in order to find out who is holding on to them and make the appropriate corrections.
Does anyone have any experience in which Strings were not being collected? Is there any way to separate the new objects created during process "X" from those that were originally required by the application so that I can know which are leaking? Any advice would be appreciated.
Thanks
**UPDATE
Ok... there is something very strange going on. I'm starting to doubt whether there is a leak at all.
Let's say that I take a memory snapshot at the Login screen which is the original starting point of the application. Imagine that there are 1000 string objects in memory at this point. Now, if I login and choose an option from the menu, I'll take a snapshot once the new screen is loaded. Let's say that loading this form increases the string count by say 50 objects. When I logout and take a snapshot again at the login screen, only 25 of those objects have been collected, the rest will stay in memory from then on.
The strange thing is that if I keep repeating this process, no further string objects will accumulate. Instead of the string count increasing by 50, only 25 will be added at this point, and those same 25 will be collected once I go back to the login screen. I'm thinking that if this were an actual leak, then each time that I opened that screen the string count would increase permanently by 25, but this only happens the first time.
This happens to me on every new screen that I open. At first there is a small permanent increase in the overall string count, but once I've loaded that particular screen, any increase in the string count during its execution will be collected once I go back to the login screen.
All of this has led me to believe that perhaps those strings are part of the inner workings of the CLR or something like that. Could it be some sort of caching done by the runtime? Perhaps it is storing my string constants for faster loading? Something like that? I hope this wasn't too confusing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您使用的是 CF 3.5,请使用 CLR Profiler 而不是 RPM。它将向您显示所有对象以及产生它们的根源。它允许您返回根树以找出它们的分配位置。
编辑
所以你是说你实际上没有遇到 OOM 或任何异常行为?听起来你在不必要的时候试图优化。这些字符串可能是 JITter 正在创建的表单标题等内容,并且如果/当对象被收集时也会被收集。不过,如果您实际上没有看到内存问题,那么它们是什么并不是特别重要。
if you're using CF 3.5, then use the CLR Profiler instead of RPM. It will show you all objects and the roots that spawned them. It would allow you to walk back the root tree to figure out where they were allocated.
EDIT
So you're saying that you aren't actually getting OOMs or any aberrent behavior? Sounds like you're trying to optimise when it's not necessary. Those string are likely things like Form captions, etc. that the JITter is creating and would get collected if/when the objects get collected. What they are, though, really isn't terribly important if you're not actually seeing memory problems.