- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
MODULE MyMod
TYPE MyType
REAL(8),ALLOCATABLE :: a(:)
END TYPE MyType
TYPE(MyType),ALLOCATABLE,TARGET,SAVE :: ArrayMyType(:)
INTEGER,SAVE :: dim
CONTAINS
SUBROUTINE Init(n,d)
INTEGER :: n,d(n)
dim = n
ALLOCATE (ArrayMyType(n))
DO i=1,n
ALLOCATE (ArrayMyType(i)%a(d(i)))
END DO
END SUBROUTINE Init
END MODULE
SUBROUTINE Test()
USE MyMod
TYPE(MyType)::p(dim)
p=ArrayMyType
END SUBROUTINE Test
PROGRAM Main
USE MyMod
INTEGER::d(2000)
d=5
CALL Init(2000,d)
DO i=1,1000
CALL Test()
END DO
END
I execute this program and watch the memory usage in task manager soar up to 206 Mbytes. Then I convert the variable "p" in SUBROUTINE Test() into a pointer:
SUBROUTINE Test()
USE MyMod
TYPE(MyType),POINTER::p(:)
p=>ArrayMyType
END SUBROUTINE Test
When the program is executed, memory usage stabilizes around 2.5 Mbytes. Similarly when I change the type definition in the MODULE MyMod to
TYPE MyType
REAL(8),POINTER :: a(:)
END TYPE MyType
I get no memory leaks with two different definitions of p in the subroutine.
Is this the expected behavior or is there a bug in the compiler? The whole reason I got into this testing is because F2003 supports ALLOCATABLE arrays as UDT components and I have read that using ALLOCATABLE arrays produces memory-wise secure (i.e. less likely to get memory leaks) code than using POINTERs. But this test shows the opposite.
I am using IVF 10.1.011 with VS2005.
Any comments will be much appreciated.
Jon
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jon,
When using
TYPE(MyType)::p(dim)
p=ArrayMyType
You create a second copy of ArrayMyType, either on stack or on heap dependent on option switches.
And third copy while deleting second copy of ArrayMyType.
And fourth copy...
When using
TYPE(MyType),POINTER::p(:)
p=>ArrayMyType
You create a descriptor for p(:), either on stack or on heap dependent on option switches. The descriptor is fairly small.
The second and later calls reused the descriptor and require no allocations
Under Windows the heap manager performs a lazy free operation. This means that when the array is deallocated (reallocated) that the deallocation is deferred (to protect against use of deallocated buffer) and the end effect is for the allocations to incrementally traverse the free virtual address space. IOW the (return to) heap is similar to a ring buffer at least up until some number/amount of returns are made then the memory gets reused.
If you use the Page File usage as an indicator of memory leak you will get a false reading since that will also include the memory returned as well as the memory currently allocated (for program and data).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the reply. Pardon my ignorance but most of your explanation was over my head. What I understand from your reply is that Windows Task Manager (I used the "Mem Usage" column to monitor the memory) is not a reliable way to check for memory leaks. I vaguely remember reading similar discussions on this forum and I think it was mentioned that there is not a good utility out there to check for memory leaks easily.
So, I assume that I can go ahead and use ALLOCATABLE arrays in TYPE definitions.
Thanks,
Jon
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jon,
You can search Microsoft's MSDN articles on memory leaks. I took a look myself and it seams as if the easy things you would like to do are cleaverly hidden from the index. e.g.
What is the total of the current heap(s) allocations
What was the largest total of the heap(s) allocations
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page