HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Memory leak causes

01-01-2004, 11:44 AM#61
Silenkiller
I think its possible to conclude that the problem here is that when a function returns it does not destroy local variables in that function. This is the way it is in all programming languages that do not have automatic garbage collection, such as C++ and obviously JASS because it is a rather primitive language (by that I mean it lacks an myriad of features that are found in modern programming languages). Since the local variables are not destroyed, every time the function is called a new block of memory is allocated for a new instance of the local variable.

Therefore, the fix would be to use global variables (one for each return type) when returning function values. This way each time the function is run, the same variable would be used and therefore not taking up any more memory.

However, there is one problem. Warcraft III uses several threads when running triggers. If two functions that return the same value were called nearly simultaneously on two different threads, one may overwrite the global variable and cause the other function to return incorrectly. I was thinking that you could create a global variable for each function, but the same function being called on two different threads at nearly the same time is still a possible scenario, albeit an unlikely one.

I hope I cleared up some questions and perhaps moved this further towards a good solution.
01-01-2004, 01:16 PM#62
AIAndy
The problem is not that the local variables aren't destroyed (they are easy to destroy as they are on the stack and not on the heap), the problem is that some of these variables are actually pointers that point to a place (the handle array) that points to a different place (probably a heap object). Now there are different scenarios where one or the other object is not destroyed causing a leak. The one that does not destroy the place on the handle array is a bug that can be avoided by setting the local variables to null after use.
To destroy the place on the heap, the appropriate native has to be called (that has to be done because there is no garbage collection),
01-02-2004, 06:23 PM#63
Peppar
Functions never run simultaneously, and can thus never use the same globals at the same time. You can always assume that the function will run to the end without interruption if it doesn't sleep.

EDIT: I'm talking about non-AI. I am horribly inexperienced in the system of the AI environment.
04-27-2004, 09:50 AM#64
MightyMonk
Quote:
Originally Posted by Peppar
I tried testing these functions. Notice the difference.

This one leaks:

Code:
function CreateLocation takes nothing returns location
    local location a = Location(0, 0)
    call RemoveLocation(a)
    return a
endfunction

This one doesn't leak:

Code:
function CreateLocation takes nothing returns location
    local location a = Location(0, 0)
    call RemoveLocation(a)
    set a = null
    return a
endfunction


Well from seeing this and compare of course the first one leaks what you did is only clean the reference to the object from the memory so the destructor could or be able to delete the object from memory and everytime you are deleting an object you should set it to null, why ?
Think a min if you wouldn't set it like you did data are still set in the memory in that specified address, also if you wouldn't use the RemoveLocation to remove the reference of the object from the memory and set the variable immediately to null, the game could crash also, why ? 'cause still there is data referenced to this address so the destructor should clean first.

I hope i explain myself well in here.
04-27-2004, 12:40 PM#65
The Gearhead
I have a question... if it's the fact that you are returning local variables at the end of a function which have a value, why don't you do this with globals;

function CreateLocation takes nothing returns location
local location a = Location(0, 0)
call RemoveLocation(a)
set udg_loc = a
set a = null
return udg_loc
endfunction

Does that leak, considering that udg_loc exists before, and after?

If so, perhaps there needs to be a shift away from locals towards more use of globals to store and return data.
04-27-2004, 12:40 PM#66
Cubasis
First of all, this is a VERY old thread, listing the discoveries that happened a very long time ago, and there have been alot of discoveries/confirmations since then, so this thread may mis-lead you. There is a reason for the unwritten rule of "No thread necromancy". Also, you must realize that none of the test-funcs in these tests are ment as a solution for you to use, they are used to "test" how much memory leaks when you loop the function a billion times. And then it's for the reader to see how they can use the solution found in these examples to make their own map leak less.

What these tests obviously indicate, is that...if you Remove your object, and de-reference ALL references to it....it won't leak a snippet. If you wanna know "why", read my "THIRD" post in this thread for most of the details: http://www.wc3campaigns.com/showthread.php?t=52643

If you're done, then conclusion: De-referencation is used to avoid the leakage of that in-between object. And the Destroy/Remove/Release functions are used to clean up the "real" object itself.

Cubasis
08-08-2004, 05:56 AM#67
MattPaintballer
Sorry to sound stupid but what is a memory leak?
08-08-2004, 06:17 PM#68
popinfresh
Set tempUnitGroup = (Units in (REGION) <gen> matching ((Unit-type of (Matching unit)) Equal to (UNIT TYPE))
Unit Group - Pick every unit in tempUnitGroup and do (Actions)
Loop - Actions

Set tempUnitGroup = (Units in (REGION)<gen> matching ((Unit-type of (Matching unit)) Equal to (UNIT TYPE))
Unit Group - Pick every unit in tempUnitGroup and do (Actions)
Loop - Actions

this is just GUI, but will it leak if this is how i handle pick every actions? im a newb at jass, so if there is a better way, please tell me the exact code.
08-09-2004, 03:57 PM#69
AIAndy
Yes, it will leak. But you can remove that leaks easily by putting RemoveGroup custom script actions between the uses of tempUnitGroup.
01-30-2005, 01:21 PM#70
Tabris
Quote:
Originally Posted by Peppar
I tried testing these functions. Notice the difference.

This one leaks:

Code:
function CreateLocation takes nothing returns location
    local location a = Location(0, 0)
    call RemoveLocation(a)
    return a
endfunction

This one doesn't leak:

Code:
function CreateLocation takes nothing returns location
    local location a = Location(0, 0)
    call RemoveLocation(a)
    set a = null
    return a
endfunction

My theory is that among other factors, Warcraft III avoids to assign a handle a new value if it suspects that there still might be a reference to that handle somewhere in the script. This way, the handle array gets huge.

1.9 million locations were created over several minutes using the first function, and the memory usage increased by 100 mb over the same period. The second method didn't have a noticable increase, so I didn't test it for as long.



This remained me Java if u dont use null, the memory wont be delete... null = i dont want anymore