I see that dumpheap -stat command is showing 5 instance of my object. When I run dumpheap -MT , it lists all those 5 instances. In theory there should be only 2 instances. Is there any windbg/sos command to trace who hold the reference to these instances.
You could use !gcroot on the object figure the root.
Related
When debugging a C# application using WinDbg, I know how to list the objects of a certain type with !dumpheap. For example:
!dumpheap -stat -type CefSharp.Wpf.ChromiumWebBrowser
Statistics:
MT Count TotalSize Class Name
00007ffa08364978 1 32 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass1f
00007ffa08336f48 1 32 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass22
00007ffa0833fa18 2 64 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass25
00007ffa08364748 4 128 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass28
00007ffa083123c0 1 824 CefSharp.Wpf.ChromiumWebBrowser
00007ffa08361fe0 115 3680 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass10
Now, I am wondering if I can execute a method of one of these objects using WinDbg. For example, I know this object has a ShowDevTools() method, how can I execute it?
TLDR: I've never seen it working until now. A related question is unanswered since 2011. If it would be easily possible, some smart people like Steve Johnson (author of SOSEX) would probably have implemented this in an extension. There's also no such command in netext. The closest there is !weval but it works on members only.
While you have a list of objects now, you'll first need to find the methods that are available at those objects:
!dumpmt -md <MT column from !dumpheap>
To call a method, there's the .call command, but it explicitly states that .NET is not supported:
Managed code cannot be called by this command.
However, .NET is not only managed. After the JIT compiler has processed the IL code, you have native code like in C++.
The !dumpmt -md command already told you whether or not the managed method has already been JITted. There are 3 possibilities:
None: the method has not been jitted
PreJIT: the method has been jitted by NGen
JIT: the method has been jitted
From !dumpmt -md you have a method descriptor, you can use
!dumpmd <method descriptor>
From there, you get a native code address, which could possibly be used for a .call. Unfortunately, the next problem occurs:
0:006> .call 011f0500
^ Couldn't resolve '.call 011f0500'
This error message means that WinDbg was unable to resolve the symbols for that method. While you have PDBs for your DLL, the JIT compiler does not produce a PDB for the JITted code.
Therefore you need to specify a prototype as defined in the documentation:
.call /s Prototype Function( Arguments )
Allows you to call the function that is specified by Function even though you do not have the correct symbols. In this case, you must have symbols for another function that has the same calling prototype as the function you are trying to call.
At this point, we have the following open questions:
where do I get a good prototype from?
what do I do if the method was not JITted?
I'm sorry that this "answer" does not resolve your issue. It may only give some insight on how difficult the situation is.
At the end of my script I use 'ie' | ForEach-Object {Remove-Variable $_ -Force}. It works fine in PS 2 (Windows 7) but PS 5 (Windows 10) throws an error:
Cannot remove variable ie because the variable has been optimized and
is not removable. Try using the Remove-Variable cmdlet (without any
aliases), or dot-sourcing the command that you are using to remove the
variable.
How can I make it play nice with PS 5; or should I just use Remove-Variable 'ie' -Force?
The recommended way to remove COM objects is to call the ReleaseComObject method, passing the object reference ($ie) to the instance of your COM object.
Here is more detailed explanation and sample code from a Windows PowerShell Tip of the Week that shows how to get rid of COM objects:
Whenever you call a COM object from the common language runtime (which
happens to be the very thing you do when you call a COM object from
Windows PowerShell), that COM object is wrapped in a “runtime callable
wrapper,” and a reference count is incremented; that reference count
helps the CLR (common language runtime) keep track of which COM
objects are running, as well as how many COM objects are running. When
you start Excel from within Windows PowerShell, Excel gets packaged up
in a runtime callable wrapper, and the reference count is incremented
to 1.
That’s fine, except for one thing: when you call the Quit method and
terminate Excel, the CLR’s reference count does not get decremented
(that is, it doesn’t get reset back to 0). And because the reference
count is not 0, the CLR maintains its hold on the COM object: among
other things, that means that our object reference ($x) is still valid
and that the Excel.exe process continues to run. And that’s definitely
not a good thing; after all, if we wanted Excel to keep running we
probably wouldn’t have called the Quit method in the first place. ...
... calling the ReleaseComObject method [with] our
instance of Excel ... decrements the reference count for the object in
question. In this case, that means it’s going to change the reference
count for our instance of Excel from 1 to 0. And that is a good thing:
once the reference count reaches 0 the CLR releases its hold on the
object and the process terminates. (And this time it really does
terminate.)
$x = New-Object -com Excel.Application
$x.Visible = $True
Start-Sleep 5
$x.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($x)
Remove-Variable x
The message "Cannot remove variable ie because the variable has been optimized and is not removable." you get, most likely means you have tried to access (inspect, watch, or otherwise access) a variable which has been already removed by the optimizer.
wp78de's helpful answer explains what you need to do to effectively release a COM object instantiated in PowerShell code with New-Object -ComObject.
Releasing the underlying COM object (which means terminating the process of a COM automation server such as Internet Explorer) is what matters most, but it's worth pointing out that:
Even without calling [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) first, there's NO reason why your Remove-Variable call should fail (even though, if successful, it wouldn't by itself release the COM object).
I have no explanation for the error you're seeing (I cannot recreate it, but it may be related to this bug).
There's usually no good reason to use ForEach-Object with Remove-Variable, because you can not only pass one variable name directly, but even an array of names to the (implied) -Name parameter - see Remove-Variable -?;
Remove-Variable ie -Force should work.
Generally, note that -Force is only needed to remove read-only variables; if you want to (also) guard against the case where a variable by the specified name(s) doesn't exist, (also) use
-ErrorAction Ignore.
I recently wrote some code using Matlab's OOP. In each class object I save some measurement data as a property and define the methods for evaluating them. With an average data set one single class object uses about 32 MB of memory.
Now I am writing a GUI that should process these objects.
In the first step I load a set of objects from a saved .mat-file (about 200 objects, 2GB on harddisk) and store them in the handles struct. They fill the RAM and use about 6-7 GB, when loaded. This is no problem.
But if I close the GUI, it seems that I can't free the used memory.
I tried different approaches with no success.
Setting the data fields to "empty" in the destructor of the class:
function delete(obj)
obj.timeVector = [];
obj.valueVector = [];
end
Trying to free it in the figure_CloseRequestFcn:
function figure_CloseRequestFcn(hObject, eventdata, handles)
handles.data = [];
handles = rmfield(handles,'data');
guidata(hObject,handles);
clear handles;
pack; %Matlab issues a warning, that pack could only
%be used from the command line, but that did
%not work either
delete(hObject);
end
Any ideas, besides closing Matlab every time after working with the GUI?
I found the answer in the Matlab Bug Report Center. Seems to exist since R2011b.
Summary
Storing objects in MAT-files can cause a memory leak and prevent the object class from being cleared
Description
After storing an instance of a class, 'MyClass', in a MAT-file, calling clear classes may result in the warning:
Warning: Objects of 'MyClass' class exist. Cannot clear this class or any of its superclasses.
This warning persists, even if you have cleared all instances of the class in the workspace.
The warning may occur for one MAT-file format, and not for another.
Workaround
Under some circumstances, switching to a different MAT-file format may eliminate the warning.
http://www.mathworks.ch/support/bugreports/857319
Edit:
I tried older formats for saving, but this does not work either. I get an "Error closing file" (http://www.mathworks.ch/matlabcentral/answers/18098-error-using-save-error-closing-file). So Matlab does not support saving class objects that well. I will have to live with the memory issues then and restart Matlab after every use of the GUI.
Based on your memory screenshots, there is definitely memory that is not being cleared. There is a small chance that you have found a fundamental flaw in Matlab's garbage collection, but it is much more likely that the ~6Gigs of memory resident data is still actually available via some series of links. Based on personal experience, here are a few ways that memory which you thought was cleared can still be available:
Timer objects: If one of the callback functions of a timer references a this data (or a copy), then that data is still available. You need to call deleted(t) on that timer.
Persistent variables in functions: I often cache data in a persistent variable within a function, this clearly allows access to that data in the future, so it will not be cleared. You need to call clear FUNCTIONNAME to clear associated persistent variables.
In GUI objects, as either data or within callback functions: The figures and any persistents need to be cleared.
Any static methods or constant attributes in classes which can retain data. These can either be cleared individually within the class, or by force using clear CLASSNAME.
Some tips for finding stale link to data (again, based on personal mistakes)
Look at the exact number of bytes being lost after each call, using the x=memory; call to get an exact count. Is it consistent? Is it a number that you recognize? Sometimes I can find the leak after realizing that it is exactly 238263232 bytes, therefore a 29782904 double array, which must be from function xyz.
See which classes are actually being deleted. Within your delete(obj) function add a detailed display or which objects are being deleted, and by inference, which are not. For a given non-deleted object, where could it be reference from? You should not need to clear data in the delete(obj) function like you are doing, Matlab should handle that for you. Use the delete function instead as a debugging tool.
Matlab has a garbage collector so you don't need to manually manage memory. After closing the GUI, all the memory will be freed except for what is in your workspace. You can clear the workspace variables using clear.
One thing I've noticed on Windows (not sure about other platforms) is that Matlab's GUI sometimes retains extra memory (maybe 100 MB, but not multiple GB like you are seeing). Simply minimizing and then restoring the GUI will free this excess memory.
When using the Allocations instrument in Instruments, you can choose between 3 Allocations Lifespans. The first 2 seem obvious:
"All Objects Created" - Every object
"Created & Still Living" - Every object still in memory
What about the third one: "Created & Destroyed"?
Is this:
1) Every object that was destroyed during the selected timespan AND created during the selected timespan
OR
2) Every object that was destroyed during the selected timespan created since the beginning of the run (regardless of the selected timespan)
The Instruments guide doesn't actually give the behavior of any of these options. I assume it is guess 1, but wonder if anybody knows for sure.
You can see the differences in the allocation lifespans by choosing Call Trees from the jump bar. The Bytes Used column illustrates the following formula:
All Objects Created = (Created and Still Living) + (Created and Destroyed)
From what I've seen, Instruments has behavior #2 for the Created and Destroyed lifespan. Instruments shows the objects that were destroyed, and it doesn't matter when the objects were created.
I have a simple question about debugging on Xcode and GDB.
I often run into an error:
unrecognized selector sent to instance 0x1081ad0
which makes the program load into GDB. Is there an easy way to examine what instance is located in that memory from GDB?
po 0x1081ad0
po = Print Object.
You can even call methods, like
po [myArray objectAtIndex:0]
Note that it only works on objects, so
po 1
will crash your program.
Steven is correct — the gdb command po is a shortcut for print-object, which actually calls -debugDescription (not -description, as you might expect) on the object provided as an argument. In many cases you'll see the same result from both methods, since one calls the other unless overridden. (See the related Note: callout on this Apple technote for details. Note that in their code sample, po $r3 prints the contents of a PowerPC register, but you can use any object pointer/reference, including Intel registers, etc.)
Also, be aware that print-object will only work on valid objects that haven't been deallocated. It won't help at all if you're sending a message to a borked pointer. Given the error you cited, though, it would seem that it's a valid object instance, it just doesn't implement the method you're trying to invoke.
It's also remotely possible that the object has already been destroyed. This answer should help in that case.
Edit:
There are other ways to "examine" objects in the debugger. I asked this SO question about Xcode data formatters, which is one way you can determine how a custom class appears in the Summary column of the debugger. The documentation linked from that question explain how it works. I've found the summary approach to help a lot with seeing the state of an object.
There are a couple of things you can do.
You can insert a break point that will trigger every time you have an exception, so basically create a break point for this (go to breakpoints and create a new one): -[NSException raise]
Alternatively, you can actually see what the object at that mem location is:
info symbol 0x1081ad0 or
info line *0x1081ad0
There's more info at the cocoadev wiki entry for exceptionhandling and debugging tips for objective C at cocoawithlove.
Your instance is not valid. You have release the object somewhere else, but you did not clear out your pointer... enable Zombie detection.