Why is in this loop memory leak?
#1
Code: (Select All)
img& = _ScreenImage
Dim P(320, 240) As Long
Dim C As _Unsigned Long, W As Long
V& = _NewImage(320, 240, 32)
_PutImage , img&, V&
For Y = 0 To 239
    For X = 0 To 319
        _Source V&
        C = Point(X, Y)
        W& = _NewImage(1, 1, 32)
        _Dest W&
        _Source W&
        PSet (0, 0), C
        P(X, Y) = _CopyImage(W&, 33)
        _Dest 0
        _FreeImage W&
Next X, Y
'creating hardware pixels done...

Beep


Screen _NewImage(320, 240, 32)
_FullScreen

'Do
'Loop
'if is my program stop here, in neverending loop, memory leak not occur.


Do
    For yy = 0 To 239
        For xx = 0 To 319
            X3D = ((xx - 160) / 160) * 3
            Y3D = ((yy - 120) / 120) * 3
            _PutImage (xx, yy), P(xx, yy)
        Next
        _Display
    Next
    '  _Display
    ' _Limit 20
Loop
'RUN THIS UNCOMPLETE PROGRAM
'look at the task manager, how our free memory is disappearing beautifully, despite the fact that this loop has no other task than to use the memory that was previously allocated.


Reply
#2
I let the code run for 5 minutes and the memory usage in my computer stayed right at 571,900K the entire time. It dipped briefly to 571,880K here and there but never exceeded 571,900K.

This was on a Windows 7 SP1 system using QB64PE 3.4.1
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#3
My memory consumption in 4 minutes is over 1 Gigabyte of RAM. Windows 7, QB64pe 3.5.0 32 bit


Reply
#4
(02-27-2023, 03:43 PM)Petr Wrote: My memory consumption in 4 minutes is over 1 Gigabyte of RAM. Windows 7, QB64pe 3.5.0 32 bit

My version of Windows 7 and QB64 is 64bit. Perhaps the difference lies there?

I just let the code run for 5 minutes in QB64PE 3.5.0 and the memory never exceeded 573,216K.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#5
Noticed a "33" in a strategic part of the source code. So all I'm saying is look into this:

https://staging.qb64phoenix.com/showthread.php?tid=1399
Reply
#6
Do
    For yy = 0 To 239
        For xx = 0 To 319
            X3D = ((xx - 160) / 160) * 3
            Y3D = ((yy - 120) / 120) * 3
            _PutImage (xx, yy), P(xx, yy)
        Next
        _Display
    Next


The problem is in the above.

Each screen is 320x240 pixels, with 4 bytes per pixel in colors, for 307kb of memory.   The FOR xx loop is running 320 times, before any _DISPLAY is ever called, so that's 98,304,000 bytes of memory in use before the _DISPLAY is called.

Hardware images all stay in memory and only render once _DISPLAY is called, so that inner loop there is using 98MB of VRAM with each iteration -- which by itself wouldn't be a "memory leak".  Where the memory leak is occurring is with the FOR yy loop being called 240 times without any delay, which is putting 240 blocks of 98MB chunks of images up into VRAM.  This memory is being drawn to and used, faster than it's being freed.  It *IS* being freed (if it wasn't, it'd quickly use 23,592,960,000 bytes of VRAM); it just isn't being freed as fast as it's being allocated and used.

On my system, things will begin to balance out around 3.7GB of memory usage; as that's the point where we finally start to free those extra handles as fast as we create and allocate new ones.

I don't think this is a true "memory leak", in as much as it's just the nature of video memory -- priority goes to creating and processing your video commands, over freeing and releasing unused memory.  In this case, you're simply just creating and using the memory faster than the OS is freeing it.  Add a delay of any sort into the process, and the issue qill quickly go away.  Smile
Reply
#7
I downloaded QB64pe 64 bit 3.6.0 and I have the same memory leak as before. I found that it takes far less hardware images to function properly (my computer's limit is 100 x 100), I don't know if it's the RAM size or the video memory size. If I oversize the field to 100,100, the size stays at the same size and there is no leakage. Interestingly.

@mnrvovrfc 
33 is correct there, I had an idea, but it could not be implemented in the intended way. I have to work around it.


Reply
#8
Steve, I read your reply now, I'm going to try it.


Reply
#9
No, my computer is weak. All I get is the program crashes into a gray window with a spinning blue circle icon followed after a while by a system error message. After all, my operating memory is probably not enough for so many hardware images, that could explain everything. The desktop computer does not work, its processor has gone to silicon paradise and the laptop has not enought power.


Reply
#10
Code: (Select All)
img& = _ScreenImage
Dim P(320, 240) As Long
Dim C As _Unsigned Long, W As Long
V& = _NewImage(320, 240, 32)
_PutImage , img&, V&
For Y = 0 To 239
    For X = 0 To 319
        _Source V&
        C = Point(X, Y)
        W& = _NewImage(1, 1, 32)
        _Dest W&
        _Source W&
        PSet (0, 0), C
        P(X, Y) = _CopyImage(W&, 33)
        _Dest 0
        _FreeImage W&
Next X, Y
'creating hardware pixels done...

'Beep


Screen _NewImage(320, 240, 32)
_FullScreen

'Do
'Loop
'if is my program stop here, in neverending loop, memory leak not occur.


Do
    For yy = 0 To 239
        For xx = 0 To 319
            X3D = ((xx - 160) / 160) * 3
            Y3D = ((yy - 120) / 120) * 3
            _PutImage (xx, yy), P(xx, yy)
        Next
    Next
    _Display
    _Limit 20
Loop
'RUN THIS UNCOMPLETE PROGRAM
'look at the task manager, how our free memory is disappearing beautifully, despite the fact that this loop has no other task than to use the memory that was previously allocated.


As you can see here, the limit is slowing things down to the point where we're freeing the memory at the same rate that we're using it, keeping us at a steady memory usage.  Wink
Reply




Users browsing this thread: 5 Guest(s)