3 ms·
One good rule I used to use and make everyone in my team use was when you get a handle write the 'anti' call at the same time. Good portions of the older windo
by sumtechguy 5y ago
One good rule I used to use and make everyone in my team use was when you get a handle write the 'anti' call at the same time. Good portions of the older windows API is allocate functions and destroy functions. If you write both at the same time your mental overhead is less.
many start using 'auto managed' style languages (c++, java, etc) where the life cycle is not as clear. The life cycle is the same though but you own it in an indirect way. Who makes it. Who uses it. Who destroys it. In some languages that is easier to do, others you own it front to back. When doing this I try to start with create/destroy then usage. It is a style that helps remove leaks before they happen. They can still slip in there...
I have used the common string thing a few times to help narrow leaks (does not work in all cases :( ). You also can use tools like valgrind, boundchecker, purify, etc. Think MS has a couple that I can not remember off the top of my head.
- tialaramex 5y agoHistorically there were two kinds of leak. Your program might grow more than intended, but eventually give everything back when it finished - or it might seize some resources permanently by mistake, so that you need to restart the computer to "fix" it. Modern operating systems mostly rule out the latter type of leak, you could leak files I guess, and of course Cloud users could leak things like S3 objects, even whole instances, but many resources are now automatically cleaned up when you exit. As a result of that though, for long-lived processes, such as Chrome but also most background tasks and server software, just "I definitely clean up the mess eventually" doesn't get the job done, the OS was going to do that too. The user doesn't care whether the resources would have been returned half a second after they closed your program when "clean_up_everything()" is called by the main thread, or, a second after that when the OS cleans everything left behind. So this is a real problem, about the actual meaning of our programs, and (though they are still a good idea) can't be helped by good programming techniques, garbage collection, Rust's Drop trait, the C++ RAII way of thinking, deferred clean-up in languages like Zig or Python, or anything else I'm aware of. We need to actually express in our programs the intent to hang on to only what's actually needed and clean everything else up as we go. And it can be sorely tempting to consider that "It gets cleaned up eventually" is good enough, that's where leaks get in.
- sumtechguy 5y agoSpot on. But as for 'right now' I have to be a bit more practical and work with what I got. Mostly these days most machines have a decent amount memory so leaks are not as noticeable, unless you look. If in the early days if I leaked 50MB of memory and my machine had 16MB. I had a real issue and the machine would be borked. If I do the same today you would not notice it. It is why I stressed watching life cycle of an object. You made this thing, who is cleaning this mess up, and when. 'When' could be anywhere from never 'I need this all the time' to bunch it up when idle/reuse (garbage collection style), or 'right now' I need this memory back right now. There are trade offs and you need to watch for that too. The write it down while you are thinking of it has served me very well over the years. I personally got bit by not following my own rule a few weeks ago. I allocated something and I had not cleaned up correctly. I got 'lucky' and that was actually the right thing to do. But in the code review I rightfully got dinged on it. One thing I wish many more docs would do is 'this makes object xyz use remove_xyz to clean it up'. Or 'this looks like it is creating an object it is not, this is returning some global'. Right there in the doc. It would help so much. That temptation of 'eventually' is one that some languages push hard. But I find many leaks that I have chased over the years were just a poor understanding of the calls being used (bad docs, not reading them, or a combo). You may have had a different experience.
- a1369209993 5y ago> can't be helped by good programming techniques, garbage collection, Rust's Drop trait, the C++ RAII way of thinking, deferred clean-up in languages like Zig or Python, or anything else I'm aware of. Arena allocation. Every allocation must be attributed to some arena (eg current tab, current network request, current frame being rendered, etc); when the arena goes away, so do all its allocations.
- tialaramex 5y agoGood idea. Not always appropriate, but there are a lot places I could have done this and didn't. Thanks.
- 5y ago
- asveikau 5y agoThe managed languages create additional hurdles for handle leaks. My prior experience with the .net GC is that it responds to memory pressure, and not necessarily to open handles. So when people write code that relies on GC for cleanup, it has a bit of a blind spot for the handles -- they don't take much memory in your process so it won't know to invoke GC. There are some patterns to help, like using().
- pitterpatter 5y agoApplication Verifier can help detect handle leaks afaik. Honestly, an amazing tool when you have a situation that calls for it.