News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Memory Leaks 'r Us'

Started by Raistlin, May 31, 2018, 03:55:35 PM

Previous topic - Next topic

Raistlin

Hi guys, Some quick and dirty questions for the discerning intellectual types.

Background: Memory Leaks - I've been playing around with Dr. Memory (open source leak detector).
The application seems to find leaks in some of my tested home-grown apps - that are of obvious concern.
Supposedly from the documentation, I shouldn't be too worried, as per example using the "no_check_leaks_on_destroy"
option should nail down most of the false positives. However I still end up with some unique reported leaks (16k in one example),
which I'll be scrupulously hunting down. But it does bother me - I wasn't so concerned about this earlier.

Anyhow - here's the questions I'd like clarity on:

1) Is explicit DeleteObject (hdc, fonts & bitmaps), DestroyIcon (icons) really all that necessary
    if ExitProcess kills all open handles and supposed default heap allocations?
    I've seen allot of example code here on the forum - that ignores Delete/Destroy....should we all be worried?

2) I always use HeapAlloc and HeapFree on a per PROC basis, is this good enough ?

3) If creating a private heap, does HeapDestroy really destroy all the related handles and free the memory ?
    Could we simply HeapAlloc (no HeapFree) as much as we like [within the confines of the allocation] - and then just HeapDestroy ?

4) What's best practice, to ensure leak reduction ?

5) I've noticed some Windows API calls [specifically: kernel32 & user32] might actually be creating leaks, such as when passing NULL pointers
    as parameters - does anyone know something about this ?

Thanks
Raistlin
Are you pondering what I'm pondering? It's time to take over the world ! - let's use ASSEMBLY...

hutch--

I have a view on memory leaks, learn from the start that when you allocate memory, design where you free the memory before you do much with it. The real solution to memory leaks is don't have any.

If you still use GDI functions, always clean them up according to the documentation or it can come back and bite you while the app is running.

> 4) What's best practice, to ensure leak reduction ?

Don't have any at all.

Its usually the case with test pieces that it does not matter but with a serious app that has to do something useful, always clean up any mess or it can make your app unreliable or if it has to run for a long time, it can start to waste resources or slow down. With the hardware multitasking that became available in Win32, the OS recovers memory after an app closes down (or is closed down) but this at least means that a leaky app has to be closed down from time to time to cover up its crappy code.

Its a discipline that you learn, allocate what you need when you need it but always design where you free the memory and if you have the slightest doubt, test the return value of the Heap/GlobalFree() to ensure it worked.

Memory leak detectors are for people who are too lazy to write code properly in the first place, if you obey the law of gravity, (what goes up must come down) you don't have any to start with.

Also be aware that the OS often uses a lazy flush with freed memory so it may not always be immediate that it disappears.

daydreamer

Actually interested if os let's you get away with exitprocess only,or is it some demo coding code style to not use all kinds release/free code to get the. Exe to fit into 1k,4k?
Does it takes x number of test run your Exe,without proper release /free,before you need to restart os,to fix too many mem leaks,that become too many so your Exe and/or os stops working properly?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Quote from: daydreamer on May 31, 2018, 09:19:58 PM
Actually interested if os let's you get away with exitprocess only
Yes, and (on rare occasions) no. See, inter alia,
Raymond Chen on ExitProcess
ExitProcess releases all resources, right?
MemState helps to find leaks in your code

The problem is that Micros**t is not very explicit about it. There are a handful of cases where ExitProcess may not be sufficient, i.e. where a program uses a shared resource. That might be global atoms, or non-private DCs. Would be great to have an official list somewhere...

Siekmanski

When I'm not sloppy, this is how I try to handle leaks.
Allocate one big piece of memory and do your own memory management. ( allocate once, release once )
For win api's always check return codes and release pointers ( memory or interfaces ) as soon as possible according to the MSDN documentation.
Creative coders use backward thinking techniques as a strategy.

daydreamer

#5
its when repeatedly testrun dx code many times,it stops working and you have to restart windows,must be some memoryleak that builds up,maybe gpu memory usage goes up part by part for each start until it wont work,or maybe other things like Creation of Surfaces that arent released properly

Memory Leak's'r Us'
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

zedd151

Quote from: daydreamer on June 01, 2018, 02:23:37 AM

Memory Leak's'r Us'

That's what starts happening once you reach middle-age (50's).    :P
And for some, much more rapidly later in life.

Sorry for the hijack.

To be on topic, the most overlooked is using font resources. Often times those resources persist in memory until the next reboot.
I have had that issue on a few occasions.

I have also seen where a handle was left open, so that memory could not be freed.  And sometimes it is tricky tracking where this is occurring. It all boils down to good programming practices. But often times there is a rush to complete a piece of code and important things are overlooked.  I admit I am a sloppy coder at times.

Raistlin

#7
@hutch :
QuoteMemory leak detectors are for people who are too lazy to write code properly in the first place

I thoughts so too, but lazy vs. ignorant doesn't sit well with me (I'am an educator after all). I've been coding in ASM for
30 odd years (on and off) and I still feel like a beginner sometimes. My thinking is - "Trust but Audit" (13th IT commandment) and thus
the use of the leak detector and this follow-up forum post.

@daydreamer:
QuoteActually interested if os let's you get away with exitprocess only,or is it some demo coding code style to not use all kinds release/free code to get the. Exe to fit into 1k,4k?

Yes - this relates to question 3 of my original post. The paradox is - "we want code small and fast" - but the "correct way" adds cycles.
Does doing it correctly make a difference (re: really no leaks ?) or can we get away with ExitProcess/DestroyHeap (re: equivalent no leaks ?).

@jj2007:
QuoteThe problem is that Micros**t is not very explicit about it.

I know, I know, I know..... :( Thus the forum post - hoping some-one does know <holding breath>

@Siekmanksi:
QuoteAllocate one big piece of memory and do your own memory management. ( allocate once, release once )

Yes - this relates to question 2 - I've been doing that pedantically - but still end up with "reported leaks" <- I'am unsure of the trustworthiness
of this information (re: Dr. Memory) - but it does concern me.

Perhaps some-one has an alternate tool ? (pure ASM macro or something ?)
Are you pondering what I'm pondering? It's time to take over the world ! - let's use ASSEMBLY...

jj2007

Quote from: zedd151 on June 01, 2018, 03:30:01 PMthe most overlooked is using font resources. Often times those resources persist in memory until the next reboot.

Raymond Chen on ExitProcess in The Old New Thing:
QuoteDon't worry about freeing memory; it will all go away when the process address space is destroyed. Don't worry about closing handles; handles are closed automatically when the process handle table is destroyed. ... The building is being demolished. Don't bother sweeping the floor and emptying the trash cans
The question is really whether fonts are any different from bitmaps, memory ranges, ... everything that sits in your address space. And unfortunately Micros**t doesn't answer that question.

Raistlin

hmmm - I've scoured MSDN and made some quick notes [copy and paste = plagiarism]
in the previous post - as an attachment - will grow it as time goes on. The info is all over
the place unfortunately......
Are you pondering what I'm pondering? It's time to take over the world ! - let's use ASSEMBLY...

hutch--

 :biggrin:

I am a "Law Of Gravity" man, what goes up must come down.

    mov pMem, rv(Global/Heap/VirtualAlloc,normal args ....)

    ; do whatcha gotta do  :dazzled:

    mov rval, rv(Global/Heap/VirtualFree, pMem)

    .if rval == 0
      conout "Didn't Work",lf
    .else
      conout "Memory released correctly",lf
    .endif

The technique for perfect leak detection.  :biggrin:

jj2007

Quote from: Raistlin on June 01, 2018, 05:28:10 PMThe info is all over
the place unfortunately...

It is, it is. MSDN now calls actions that really should be performed on ExitProcess "critical finalizers" (I found this by reading all the comments at TheOldNewThing):
QuoteClasses deriving from the CriticalFinalizerObject class are implicitly treated as a constrained execution region (CER). This requires code in the finalizer to only call code with a strong reliability contract. For more information about CERs, see the System.Runtime.ConstrainedExecution namespace.

In classes derived from the CriticalFinalizerObject class, the common language runtime (CLR) guarantees that all critical finalization code will be given the opportunity to execute, provided the finalizer follows the rules for a CER, even in situations where the CLR forcibly unloads an application domain or aborts a thread. If a finalizer violates the rules for a CER, it might not successfully execute. In addition, the CLR establishes a weak ordering among normal and critical finalizers: for objects reclaimed by garbage collection at the same time, all the noncritical finalizers are called before any of the critical finalizers. For example, a class such as FileStream, which holds data in the SafeHandle class that is derived from CriticalFinalizerObject, can run a standard finalizer to flush out existing buffered data.

Just in case you didn't understand anything: Yes, you should flush buffers by closing file handles before calling ExitProcess.