HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Memory leak causes

10-29-2003, 04:35 AM#46
MarSara
I know you all just dismissed my post but, think of it this way:

First of all all variables you declare must have a place in memory, and because of how JASS lets you declare variables, and because Wc3 was most likely programed in C++, each varaible you declare must have a "pointer"to reference it.

pnReference = new int;
*pnReference = 0;


Now, pnReference holds the memory location of a newly allocated integer and the value is set to 0.

Although you can call delete [variable] to "de-allocate" it, the remove function most likely don't call this, because the variable can still be used after that point. Think of it this way, RemoveLocation(...) doesn't delete the varaible, but rather the location itself. Also, if a function is called, then called again before the first finnishes, then the allocator must allocate memory for a second copy of the variable(s), so they don't interrupt each other. Now WarCraft III won't delete these variables because they were used once and can possibly be used a second time. So with each overlaped function call, a new variable is defined and will also take up memory. Also remember, every function call takes time, and if Wc3 deleted varaibles as soon as they weren't needed, the system requirments would increase, not to mention "fragmentation" would occur (RAM-fragmentation, not HD-fragmentation), which would make "memory leakage" even worse. I've also noticed that when Wc3 needs to construct a variable, say a string, every time you concatinate another string to it, that string is given a memory location and defined as a variable, then only removed once that function is called again (then again it is only delete as needed).

The only thing that confuses me, is that you claim setting a variable to NULL deletes it from memory, which should only set its value to 0.

I know alot of you are going to probally just dismiss this post too, and if you do then I'll just quit trying to explain it, but I am a programmer and I know what I'm talking about.
10-29-2003, 07:24 AM#47
PitzerMike
marsara: 0 and null is not the same. 0 is the value 0 while null means that the variable doesn't have a value at all.

And we know global variables can't be recycled after the object they're pointing at is destroyed because they could be used again.

But what we are talking about is local variables and these are not needed anymore after execution of the function they are declared in.
10-29-2003, 08:35 PM#48
Nozdormu
Quote:
Originally posted by MarSara
I know you all just dismissed my post but, think of it this way:

First of all all variables you declare must have a place in memory, and because of how JASS lets you declare variables, and because Wc3 was most likely programed in C++, each varaible you declare must have a "pointer"to reference it.

pnReference = new int;
*pnReference = 0;


Now, pnReference holds the memory location of a newly allocated integer and the value is set to 0.

Although you can call delete [variable] to "de-allocate" it, the remove function most likely don't call this, because the variable can still be used after that point. Think of it this way, RemoveLocation(...) doesn't delete the varaible, but rather the location itself. Also, if a function is called, then called again before the first finnishes, then the allocator must allocate memory for a second copy of the variable(s), so they don't interrupt each other. Now WarCraft III won't delete these variables because they were used once and can possibly be used a second time. So with each overlaped function call, a new variable is defined and will also take up memory. Also remember, every function call takes time, and if Wc3 deleted varaibles as soon as they weren't needed, the system requirments would increase, not to mention "fragmentation" would occur (RAM-fragmentation, not HD-fragmentation), which would make "memory leakage" even worse. I've also noticed that when Wc3 needs to construct a variable, say a string, every time you concatinate another string to it, that string is given a memory location and defined as a variable, then only removed once that function is called again (then again it is only delete as needed).

The only thing that confuses me, is that you claim setting a variable to NULL deletes it from memory, which should only set its value to 0.

I know alot of you are going to probally just dismiss this post too, and if you do then I'll just quit trying to explain it, but I am a programmer and I know what I'm talking about.


You've got to be a pretty inexperienced programmer to think that NULL and 0 are the same thing, not to mention that int is a basic type and does not use references, especially in C++.
10-29-2003, 09:34 PM#49
Cacodemon
Nozdormu:

Test following function then say MarSara is unexpirienced JASS programmer or not:


Code:
 function TestHandle takes nothing returens nothing
 local integer array TestIntArray
 set TestIntArray[0] = 0
 if TestIntArray[0] == null then
  call DisplayTextToForce(GetPlayersAll(),"MarSara is RIGHT!!!")
 else
  call DisplayTextToForce(GetPlayersAll(),"Oh NO, I'm RIGHT!!!")
 endif
endcode

Any questions? :-)
10-29-2003, 09:39 PM#50
Cacodemon
You know well that handle is just integer points to memory location. I guess JASS null is integer equal to 0. So Warcraft core doesn't destroy data but only handle! And I have reasons to guess this idea =)

P.S. Just test my example =)
10-30-2003, 05:26 AM#51
Nozdormu
Well, yeah it's true for basic types. I should have clarified. However, most variables that cause leaks are not basic types.
10-30-2003, 06:44 PM#52
Starcraftfreak
What about going to the Bnet forum and telling BWood about the local variables leak? Maybe they will even include it into 1.13!
10-31-2003, 01:28 AM#53
MarSara
Apparently you guys don't undstand. I don't care how good of a programmer you are, once you start using a "registry system", you can't stop memory leakage, as you so call it.

And what I mean by a "registry system", is that you use an array of pointers to hold the addresses of all the varaibles, along with other arrays to hold their type, size, etc... So posting on the Bnet forms will get you nothing, because it can't be fixed, only optomized, which Blizzard has nearly already done.

@Nozdormu, in C++ a handle is technicaly a "basic type", so is everyting derived from a handle, the only true non-basic types are structures/classes (which contain basic types, or other structures/classes) I though you might also like to know I have made a RTS game, and I also ran into the "memory leakage" issue, which I did my best to reduce, but couldn't eliminate.
10-31-2003, 09:39 AM#54
AIAndy
I think you are the one who does not understand the issue. Of course it is not possible to prevent memory leaking completely.
Look at the examples given. They are pretty similar to each other. But by slight differences you cause a big difference in the leaking. This is due to a bug and not due to memory fragmentation. And what you write in the script is in no way directly represented in a C++ data type. Handles are not first class pointers. That has been proven by attempts to change their contents (with the bug that allows to convert data types). Instead there is a layer in between, the handle array (I call it that although it is not proven that it is indeed an array). When a handle points to null, no place in the handle array is used. Using the different Create natives you create a spot in the handle array and an object that is probably stored in the heap and the pointer to that is stored in that place in the handle array. Using the remove natives removes the object in the heap but not the place in the handle array. That is probably done so that an alias handle cannot point to another object that might be created afterwards (a kind of tombstone system). To be able to remove the place in the handle array there seems to be a reference counter that counts all handles that point to that place. That counter is properly reduced when you assign null or another value to a handle but not at the end of life for local variables. That is the bug and it can of course be fixed. Now one could think that with the reference counter one could live without the remove natives and just delete the associated object when the reference counter reaches 0. But that is not possible because many of the objects handles can point to can live without being referenced anywhere in script variables (special effects, units, ...).
11-27-2003, 05:46 AM#55
Aristotle
I'm a noob when it comes to jass and I'm not sure what you mean by memory leak but I found a normal trigger that causes WC3 to crash.

Any event
No condition
Action: Trigger-Run this trigger

The reult is that your computer closes warcraft to save itself from overload, however I'm not sure this is always the case, my friend tested this trigger and his computer turned off. It may be dependant on your operating system. The best thing about it though is that there is no fatal error and no explanation.
11-27-2003, 11:37 AM#56
Cacodemon
It's not a bad trigger, it is just bad logic. You start infinite loop which causes memory overload...

Another example:

event - every 0.01 second
action - create 100 units of any type...
11-27-2003, 01:06 PM#57
Aristotle
The only difference is that mine has an infinitly high memory requirement, as soon as you've repeated it the 50th time you have to do it a 51st, as soon as you've done it a 51st time you have to do it a 52d time. And so one, causing instant overload and WC3 shutdown. Your example could take a while.
12-26-2003, 03:47 PM#58
jmoritz
But I'm gonna reply anyway :)

MarSara, either you have not read the entire thread, or you are not as experienced as you claim to be. I hope it is the former. Your entire story about overlapping local variables is very true and correct, but also very irrelevant. Read the entire thread to find out why.

Cacodemon, yeah I used exactly that fix for PolarProjectionBJ in my map :) Off topic: how fast can you get a unit to move in 1.13?


Has anyone checked any of these issues in 1.13?
12-26-2003, 07:05 PM#59
Vexorian
The guys of the JAss vault told me that they still are there
12-28-2003, 07:42 PM#60
dataangel
Yes the issues still exist in 1.13. However, in my own tests if you destroy your special fx, groups, and locations, you're good. Having done this Battledome no longer experiences any insane lag or unload times. I recommend you guys check out the JASS vault functions with the names xxxxMakeTemporary, and the timed special fx functions. Even if it is still causing a small leak, it should be neglidgible enough not to affect your map, seeing as a map with Battledome's complexity can run just fine.