A Few Questions
1) Is there a way to force the garbage collector using the command line?
2) Is the Retention Path the order of the objects while call stack is the order of methods? You can double-click
on these objects to find the method calls. Is that correct? (Feel free to provide any additional info or links.)
3) Does the object address (under instances) give us any information we can use?
4) What does the snapshot comparison below indicate? My colleague and I have two different interpretations of what is depicted here. I'll do my best to explain both interpretations. Please tell us which of the two is correct, if either is, and why or why not.
Interpretation 1:
It is no mere coincidence that we see 4 new objects and then 4 dead objects in row 2. There were 4 new objects in snapshot 1 and those 4 objects were dead in snapshot 2--none of them survived. This is backed up by the number of new and dead bytes. While not conclusive, the new and dead bytes consistency suggests these are the same objects--not previously surviving objects though they could be. (If they were all merely previously surviving objects, one might expect the byte sizes to be different quite often because they are totally different objects with their own attributes.) This interpretation is evident because of the consistency between the number of objects and their byte sizes throughout the image. Why so often are the numbers and sizes the exact same? (It need not always be the same objects. It could be previously surviving objects of the same size, but generally, they are the same.)
Interpretation 2:
The previous observation is merely coincidental! New objects and Dead objects are mutually exclusive! Between the two snapshots 4 new objects appeared and 4 different objects died. When comparing two snapshots, 4 objects can't be alive and dead at the same time. The number and size are simply coincidental. Perhaps all the objects are the same size. The code generates thousands of objects in memory, many of which are similar, but not the same object. So their sizes are quite naturally similar if not exactly the same. But the dead objects are ALL previously surviving objects--not possibly the same objects as the new ones. Why then are the numbers often the same? Simple coincidence. Perhaps, the system is allotting space as those spaces become available or the GC is wiping out objects in a regular and systematic way.
Thanks very much for addressing this. If either interpretation is true, pick one and explain why or why not. This would be very helpful.
Please sign in to leave a comment.
Hi Keokistevenson,
thanks for your questions.
Yes, you can do it by passing the following service message to console dotMemory:
##dotMemory["force-gc", {pid:<PID>}]
Use
dotMemory.exe help
anddotMemory.exe help service-messages
to learn how to use service messages to control the profiling session.Do you mean “Key Retention Paths” view for object instance? This view presents a number of retention paths for an object instance. which differ from each other most significantly.
If you mean the “Group by Similar Retention” view for an object set, this view shows objects grouped by similarity of their retention paths and shows the two most dissimilar paths.
You can examine examples here and here to get information about what the retention paths are. Bear in mind that all objects and their references are represented by graph, not by tree in opposite to call stacks.
This data was requested by users who analyze Windows memory dump in dotMemory and WinDbg at the same time. This address allows finding the object instance in WinDbg.
The Comparison view provides details on how many objects were created between snapshots and how many objects were collected. If there should be no new instances of some type but there are, then it is, probably, the cause of the leak.
Comparison view presents the following information:
Survived objects
are the objects that exist in both compared snapshots. These object instances were created before the oldest snapshot and remained in memory on the moment the most recent snapshot is taken.
New objects
are the objects that don't exist in the oldest snapshot but exist in the most recent snapshot. These object instances were created somewhere between the compared snapshots.
Dead objects
are the objects that exist in the oldest snapshot but don't exist in the most recent snapshot. These object instances were collected somewhere between the compared snapshots.
You can read more about snapshots comparison concept in dotMemory help.
Now you and your colleague can decide for yourselves which concept is correct. I would just like to add that all instances of the same class have the same size. Do not confuse the amount of memory retained by an object (“(minimum) retained bytes”) with the amount of memory occupied by the object itself (“bytes”). The concept of retained memory is explained in this article.
Thanks Ed! I really appreciate your prompt response – it's incredibly insightful!
However regarding question #4, we really need clarity. While we've diligently studied the documentation, each of us is still convinced of our own interpretation. It would really help to have an explanation that addresses the data and argument provided.
Is there another way I can resolve the issue in #4? Its impact on our approach to handling memory leaks is significant.
Once again, thank you all for your assistance!
Of course anyone can respond including Ed.
Best wishes!
Interpretation 2 is the right one.
As I said in the previous post:
* The size of all objects of the same type is the same
* Dead objects were Live in the oldest snapshot and died before the most recent snapshot. New objects were allocated after the oldest snapshot and are live in the most recent one. They can't be the same. Objects which are created after the oldest snapshot and already died before the most recent one are named “Memory traffic” and some statistical information about them you can find in the “Memory allocations” view.
The fact that your screenshot shows the same number of new and dead objects is a coincidence. Maybe some component, like view, was destroyed and created again somewhere between the snapshots, and that explains the equal numbers, I can't say with certainty.