I got assigned an interesting bug to fix today at work: Performing a certain operation in our program caused an enormous memory leak, producing a FastMM report file that weighed in at over 150 MB, representing a serious amount of RAM in our program. A bit of debugging made it obvious that a certain interfaced object was at the root of the problem, and it had a refcount of 1 when the program ended. I found the object that was holding a reference to it and went looking for what was holding it up… and it turned out to have a refcount of over 4700 when the program ended! Continue reading ‘Memory management: still a non-issue’ »
Archive for the ‘Memory Management’ Category.
As I pointed out yesterday, with FastMM available, memory management is so much of a solved problem that it’s a non-problem. So dropping a performance-killing pseudo-GC “solution” on us is patronizing and insulting in the extreme, not to mention a massive waste of effort that could have been spent actually improving the language and/or standard libraries. But I did notice one very interesting thing from its implementation: the introduction of the [Weak] attribute, and a few other related attributes, are something fundamentally new in the Delphi language. Continue reading ‘How to simplify memory management the right way’ »
There’s been a lot of talk recently about immutable strings in the iOS compiler, which, as Marco pointed out, is not actually implemented (yet) but is just something that’s under consideration. And it appears that he’s uncomfortable with the removal of AnsiStrings. That’s a good thing, IMO. I think they should be put back, particularly for UTF-8 strings. Continue reading ‘NextGen: Delphi’s “Visual Fred” moment?’ »
One of the awesome things about FastMM is FullDebugMode. Its features pretty much make memory leaks trivial to track down… usually. But if you’ve got the classic problem of code creating objects and placing them in a container somewhere and then abandoning them, you can have a huge memory leak in your program without it ever being detected, just as long as the container gets properly cleaned up before the program shuts down.
Seems to me that it should be possible to detect this with a bit of instrumenting, though. Here’s the basic idea. Continue reading ‘Wanted: live leak detection for FastMM’ »
For the TURBU engine, I’ve got a custom control that allows me to embed an OpenGL rendering context on a form. I was working on some new features, and I downloaded gDEBugger, an OpenGL debugging tool, to help out. One of the things it told me is that my rendering contexts were leaking. Continue reading ‘A handle leak in TWinControl?’ »
One of the biggest challenges in working on the TURBU engine has been minimizing load times. Some large projects have a whole lot of data to work with, which could take the better part of a minute to load if I tried to load it all up front. No one wants to sit and wait for that, so I’ve pared down the loading so that only the stuff that’s needed right away gets loaded from the project database right at startup.
And yet, on one of my larger test projects, that wasn’t enough. One of the things that has to be loaded upfront was map tile data, so that the maps can draw. Unfortunately, this project has over 200 different tilesets, and it was taking quite a while to load that much data. I’ve got a RTTI-based deserializer that can turn dataset records into objects, but it was taking a completely unreasonable 3.3 seconds to read the tile data.
Most of my posts on here have been about technical subjects, geared towards moderate-to-advanced Delphi coders. This one’s to help out the beginners who are still learning the ropes. I’d like it to be something that people can send new users to from StackOverflow or other sites if they’re having trouble figuring out how to clean up their memory properly.
I’ve never really understood why people find memory management difficult. Maybe I just “get it” for some reason, but it’s never seemed all that arcane or complex to me. In all my time working with Delphi, I’ve only run into one truly difficult memory management scenario, and it’s something that most people won’t ever have to deal with: sharing global interface references across package boundaries. If you do that wrong, you’re likely to run into some very strange errors at program shutdown that are hard to debug.
But people keep asking questions about the basics of what to free and how to free it on StackOverflow, and from answering them and analyzing the questions and the answers, it seems to me that the entirety of memory management can be boiled down to one single principle.