View previous topic :: View next topic |
Author |
Message |
ursuselasticus
Joined: 26 Mar 2005 Posts: 71
|
Posted: Tue Sep 27, 2022 6:37 pm Post subject: Memory leaks by pointers to derived data types? |
|
|
Hi there,
currently I have a problem with leaking memory and I am at my wits end to track it down. The code is rather long, so no sense in posting it here, but I try to describe how my program works.
My variables are of derived type, a mixture of integers and reals, no matrices or arrays. They are organised in a linked list. The type definition of variables and pointers are done in a module, each procedure to access the data has a use-statement to this module
In a loop new data are generated which are sorted into the linked list and some data are destroyed. The list typically holds bout 3,000 to 4,000 items with about 40 to be added and removed each time my main loop is processed.
For debugging I have a count of allocations and deallocations running which shows a balance exact as it should be, namely the number of the active items as open allocations.
Some procedures to manipulate the data use their local set of pointers which get nullified manually when the precedure terminates.
But still I have an increase of memory as monitored with Task Manager from about 28 MB at startup to 76 MB after 3,000 cycles, while the memory consumption is about 36 MB when my linked list is fully loaded.
So what can I do?
Is there a useful strategy to track down this memory leak?
Are there tools around to check for memory leaks?
Should I use another approach?
I am using Plato and FTN95 version 8.80, compiling /64 and running in a windows 11 environment. I use clearwin+ with format windows with /og graphic.
Any idea? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Sep 27, 2022 10:10 pm Post subject: |
|
|
Try using /debug and stepping through the code using the debugger, watching the memory increase via the Task manager as you step through.
If you are happy with your own direct memory usage, look out for changes when entering and leaving ClearWin+ code. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Sep 28, 2022 2:49 am Post subject: Re: Memory leaks by pointers to derived data types? |
|
|
ursuselasticus wrote: | Some procedures to manipulate the data use their local set of pointers which get nullified manually when the precedure terminates. |
If the pointers are associated with allocated memory, this memory must be deallocated. I think that to only nullify would leak the memory.
Nullify or redirecting pointers will loose the address of the previous allocated memory and so then be leaked.
Also with allocated components of derived types, these must be specifically deallocated, reversing through the derived type structure.
( this is a great approach for flexible data structures, but be careful with small allocated components as there is a memory overhead with tracking the size of these allocatable components. )
What compile option are you using, as /check did at one time leak memory on deallocate. Not sure if it still does. You are using /check, try /debug and see if that changes the memory status. |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Wed Sep 28, 2022 4:16 am Post subject: |
|
|
I've been using:
Code: | if(associated(item)) deallocate(item) |
This prevents an error if you deallocate something that hasn't actually been allocated. However, it obfuscates deallocation of memory when you didn't allocate it first.
I don't use NULLIFY for an actual allocation. I will use it if I am passing a pointer to memory in a callback routine that allocates using that pointer. JIC.
Just a thought.
Bill |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Wed Sep 28, 2022 7:16 am Post subject: |
|
|
John
I am not aware of any memory leak problems with /check.
32 bit FTN95 with /check allocates memory in a special way, allocating large chunks at a time and then micro-managing the user allocation. But even there I am not aware of any outstanding issues. |
|
Back to top |
|
|
ursuselasticus
Joined: 26 Mar 2005 Posts: 71
|
Posted: Wed Sep 28, 2022 11:43 am Post subject: |
|
|
Thanks for your response.
I was able to pinpoint the source of my memory leak - but I am at a loss on how to solve it. The following code is the essence of my approach - and highlights in fact two problems:
Code: |
program MemoryTest
type mytype
real rA (100,100)
integer iB (100,100)
endtype
type (mytype) tC
type (mytype), pointer :: pC, pD
tC%rA = 2.0
tC%iB = 3
do j = 1, 100000
allocate (pC, stat = iStat)
if (iStat .ne. 0) then
print*, 'Allocate went wrong, iStat = ', iStat
stop
endif
pC = tC
pD => pC
deallocate (pC, stat = iStat)
if (iStat .ne. 0) then
print*, 'Deallocate went wrong, iStat = ', iStat
stop
endif
if (associated (pD)) print*, j
enddo
end program
|
First: It produces a considerable memory leak. It does not help to nullify pD prior to deallocating pC. The memory loss remains the same.
And Second: The 'if associated' statement fails to recognize that the pointer pD is not associated any more due the pointer it pointed to being deallocated.
Program compiled by FTN95 v. 8.80, \64, Windows 11.
Cheers
Norbert |
|
Back to top |
|
|
ursuselasticus
Joined: 26 Mar 2005 Posts: 71
|
Posted: Wed Sep 28, 2022 11:58 am Post subject: |
|
|
Still messing around with this little program. Here is the ultimate essence to produce this memory leak.
Code: |
program MemoryTest
type mytype
real rA (100,100)
integer iB (100,100)
endtype
type (mytype), pointer :: pC
do j = 1, 100000
allocate (pC, stat = iStat)
deallocate (pC, stat = iStat)
print*, j ! slow down execution a bit
enddo
end program
|
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Wed Sep 28, 2022 1:47 pm Post subject: |
|
|
There will appear to be a memory leak when using /CHECK (or any option that implies /CHECK) because (up to a certain limit of total memory used) memory is not actually released to the system. This is to allow checking for dangling pointers.
In order to avoid this part of the checking mechanism, use /INHIBIT_CHECK 4 or in some situations /INHIBIT_CHECK 3.
After testing and debugging it is normal to switch off /CHECK etc.
Sorry I did not think of this earlier. |
|
Back to top |
|
|
ursuselasticus
Joined: 26 Mar 2005 Posts: 71
|
Posted: Wed Sep 28, 2022 2:48 pm Post subject: |
|
|
Thanks a lot.
Problem solved.
Cheers
Norbert |
|
Back to top |
|
|
|