|
Antwort |
Registriert seit: 4. Jun 2010 15.473 Beiträge |
#1
As I've made clear many times in conference talks I’m a big fan of FastMM4, the full version Delphi’s built-in memory manager (I haven’t yet tried out FastMM5, which is fully rewritten but now has either a GPL or a commercial license). FastMM4 is great for identifying memory leaks, memory corruption, interface misuse and so on, and locating the source of the problem via a call stack. However it is true that the business of working through the FastMM4 reports is somewhat manual – reports and call stacks are sent out via debug strings or log flies and then you have to pore over the details and work things backward to the source of the problem. It does the job, but takes a back seat once the details have been discovered.
Some while back I got pointed in the direction of another leak detection tool, Deleaker from Softanics, of which I hadn't heard at that point. It’s taken me a while to clear my desk sufficiently to check it out but I’m pleased to have done so, as it’s a very nice and helpful tool. I should mention up front that this is a commercial tool, like FastMM5 (when not used with the GPL license) and unlike FastMM4, Delphi LeakCheck, MemCheck 1 and TCondom 2. It costs $99 for a home license and $399 for a single developer license. Some key points about Deleaker:
The list of entity types that can be tracked looking for leaks is impressive:
Here you get a flavour of what is on offer. You can see we have support for taking and comparing snapshots, which is the mechanism we use to identify leaks in the application. There is a button to invoke the resource usage graph, which allows you to see a dynamic representation of resource consumption over the last 60 seconds. Let’s do a simple test on a simple memory leak by some code like this: procedure TForm1.Button1Click(Sender: TObject); begin var P: PByte; GetMem(P, 1024 * 1024); end;Running this up and battering Button1 shows this in the resource graph. The initial slope up was the application startup and the addition rise was the memory allocations caused by the button presses. OK, that gives a view of consumption and in a real application potentially indicates an issue, so now we can use snapshots to look for a potential problem. The idea is to take an initial snapshot (using the Take Snapshot button) as a baseline, then shortly thereafter take another snapshot and compare the two. You can then see all the allocations that have not been deallocated and look for any you weren’t expecting. When you press Take Snapshot Deleaker briefly freezes the information and collates a whole bunch of information it requires. This includes building up call stacks for each allocation that has not been freed. Deleaker understands about the symbol information format used by Delphi and C++Builder. But additionally, since it also operates within Visual Studio it understands Microsoft’s symbol format and has support for using the Microsoft Symbol Servers. This means that where necessary call stacks will include detailed information about Microsoft OS DLLs. This animated GIF shows Deleaker acquiring its data for the first snapshot. Note that the symbols shown towards the bottom of the screen at the end of the animation are not representative of what you will actually see. Current versions of Deleaker will "demangle" these "mangled" symbol names to provide a more readable stack trace. After the first snapshot I press Button1 and then take a second snapshot. Now I have Snapshot #1 and Snapshot #2. The Compare with… button can then instigate the comparison between the current snapshot and another one: This now shows the differences between the two. Here we see a single unfreed allocation of Heap memory of size 1048576 (which is 1024 x 1024) and Deleaker shows the source file and line number of the allocation as well as the call stack leading up the allocation. Double-clicking on any entry in the call stack (either your code or RTL/VCL code) will take you to the relevant location in the relevant source file (or you can use the Show Source Code button). In leaks coming just out of your own code the fact that MS symbols are available is neither here nor there. By default Deleaker doesn’t even trouble you with them in the call stack: the Show Full Stack checkbox is unchecked above. However if you need the extra detail then you can enable that option. Here is an unfreed memory allocation coming from a callback routine being invoked by the Windows API EnumWindows with full stack shown: This time I’ll leak a Delphi object: a TList. If used as before the Allocations list shows that there is an unfreed allocation of a Delphi object. However if we go to the Delphi Objects view we can see that the unfreed item is confirmed as a TList: Of course if a more complex object is leaked, such as a component like a TButton, which itself creates a number of objects for its own purposes, then the list of unfreed objects becomes larger, but all these have the same call stack: So far we’ve just looked at heap allocations, be they of basic memory or of object instances. One of the compelling features of Deleaker is that it also tracks various Windows resources not tracked by many other utilities (see list from earlier). Here, for example is a GDI handle leak: const pattern: array[0..3] of cardinal = (10, 1, 1, 1); var lb: TLogBrush; pen, oldpen: HPEN; begin lb.lbStyle := BS_SOLID; lb.lbColor := RGB(255, 0, 0); pen := ExtCreatePen( PS_COSMETIC or PS_USERSTYLE, 1, lb, length(pattern), @pattern); if pen 0 then try oldpen := SelectObject(Canvas.Handle, pen); try Canvas.MoveTo(0, 0); Canvas.LineTo(ClientWidth, ClientHeight); finally SelectObject(Canvas.Handle, oldpen); End; finally // DeleteObject(pen); // Oops! We forgot to deallocate the handle! end; end;In this case the snapshot comparison shows up 3 unfreed allocations for a block of heap memory and two HPENs (pen handles) with the Leak type set to . Note that the Leak type dropdown could be set to GDI objects to focus in on the HPENs. Looking at the call stacks for each I can readily see the one I forced: Incidentally the resource usage graph will track whatever resource type you wish. Here it is showing my test app consuming more and more HPENs as I keep pressing my button. During my experimenting with Deleaker I have bumped into several bugs and shortcomings and have passed them all along to Artem from Softanics, who is usually quick to respond. One issue had already been fixed by the time I reported it and another was fixed quite promptly. A couple of shortcomings (Delphi mangled symbol names not demangled, and RTL/VCL source files not being automatically located) were also addressed in version 2020.27.0.0. This responsive experience was reassuring. I like Deleaker – the IDE integration of the UI (especially the call stack entry support for double-clicking to see the source code) makes it much more straightforward to work with that FastMM4. But of course for all that convenience there is a price tag. Whether you can justify spending out for the sake of convenience will be a personal decision, but if you can I think you will be happy you did. Additionally, if you fear you are leaking resource handles and are having trouble tracking down how this is happening then making use of this sort of tool will expedite the resolution of such issues. 1. OK, that hasn’t been updated in some years... 2. Yeah, this one is also somewhat stale, and required a cached Google page as the EDN page it was on is no longer available Weiterlesen... |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |