| 08-16-2005, 08:58 AM | #1 |
I have no idea what is going on, but memory leaks in my map are so bad that after 30-40 minutes of gameplay, its almost impossible to continute playing. I have read the FAQ on memory leaks, and I have taken several steps toward removing the leaks but they are still just as bad as before. After EVERY (Unit Group - Pick Every Unit in Unit Group and Do Multiple Actions) I have a Unit (Group - Destroy Unit Group (last created unit group)) After EVERY (Special Effect - Create Special Effect on Unit) I have a (Special Effect - Destroy Special Effect (last created special effect)) Every time I set a point variable, I destroy it when I am done. In every single-run trigger, I destroy the trigger when it is done. After I pick a player group, I destroy the group. After a creep dies, I remove it from the game. For some reason, it takes me 10+ minutes to exit the score screen after a 40 minute game. The only things I can find that may be causing memory leaks are these: For each (Integer A) from 1 to 5, do (Actions) Loop - Actions Unit - Create 1 Flash Beam4 for (Triggering player) at ((Position of (Triggering unit)) offset by 150.00 towards (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees) facing (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency Animation - Change (Last created unit)'s animation speed to (150.00 / (Real((Integer A))))% of its original speed Animation - Change (Last created unit)'s size to (((25.00 + (2.50 x (Real((Level of Kamehameha for (Triggering unit)))))) x (Real((Integer A))))%, 100.00%, 100.00%) of its original size Unit - Create 1 Flash Beam3 for (Triggering player) at ((Position of (Triggering unit)) offset by 150.00 towards (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees) facing (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency Animation - Change (Last created unit)'s animation speed to (100.00 / (Real((Integer A))))% of its original speed Animation - Change (Last created unit)'s size to (((50.00 + (3.50 x (Real((Level of Kamehameha for (Triggering unit)))))) x (Real((Integer A))))%, 100.00%, 100.00%) of its original size I'm not even completely sure that would cause enough leaks though.. maybe if it was used enough times? But I dunno, it just doesn't seem like something that would run enough to cause so many leaks. Maybe some of you know what else might be causing these leaks? Is there anything I left out that I should dispose of after it has served its purpose? |
| 08-16-2005, 09:04 AM | #2 |
For each (Integer A) from 1 to 5, do (Actions) Loop - Actions Unit - Create 1 Flash Beam4 for (Triggering player) at ((Position of (Triggering unit)) offset by 150.00 towards (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees) facing (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency Animation - Change (Last created unit)'s animation speed to (150.00 / (Real((Integer A))))% of its original speed Animation - Change (Last created unit)'s size to (((25.00 + (2.50 x (Real((Level of Kamehameha for (Triggering unit)))))) x (Real((Integer A))))%, 100.00%, 100.00%) of its original size Unit - Create 1 Flash Beam3 for (Triggering player) at ((Position of (Triggering unit)) offset by 150.00 towards (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees) facing (Angle from (Position of (Triggering unit)) to (Target point of ability being cast)) degrees Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency Animation - Change (Last created unit)'s animation speed to (100.00 / (Real((Integer A))))% of its original speed Animation - Change (Last created unit)'s size to (((50.00 + (3.50 x (Real((Level of Kamehameha for (Triggering unit)))))) x (Real((Integer A))))%, 100.00%, 100.00%) of its original size the texts in bold leaks, they are point/location leaks. |
| 08-16-2005, 09:18 AM | #3 |
Aditionaly, the whole polar projection itself creates another point object that leaks. So, you use 3 points alltogether in your trigger, the position of triggering unit, the target point, and the polar offset of the first towards the second. Set these 3 points to variables when you start the trigger and destroy them with RemoveLocation() when you're done. It's also possible there are other critical leaks in the map, if this spell isn't cast very often, then these leaks alone can't cause all your problems (although you do leak about 50 location objects and 10 unit groups whenever it runs) |
| 08-16-2005, 09:25 AM | #4 |
oh ye, forgot about the unit group leaks. 1 way of fixing that easily (aint the best though) is to add this custom script right under the Unit - Create N Units At Position.... Custom Script: call DestroyGroup(bj_lastCreatedGroup) btw, welcome back ani :D |
| 08-16-2005, 09:33 AM | #5 | ||
Quote:
Okay I set them each to variables and destroyed them after the trigger is finished running. The spell is not casted very often, but there are about 5 other spells just like this one that probably leak as well. If there are 6 players in the game over a period of about 30 minutes, chances are this spell will get casted about 20-30 times. So I can remove the location leaks, what about the unit groups? The units created in these triggers have a negative HP regen, and I have a seperate trigger to remove them from the game after they die. I'm guessing this trigger leak as well: DumDeath Copy 8 Events Unit - A unit Dies Conditions (Unit-type of (Dying unit)) Equal to Masenko Target Actions Unit - Create 1 mesenko blast for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing (270.0) degrees Unit - Create 1 mesenko blast2 for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing (270.0) degrees Unit - Create 1 mesenko blast3 for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing (270.0) degrees Unit - Create 1 mesenko blast4 for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing (270.0) degrees I already knew that trigger would leak, but would the (Position of (Triggering unit)) handle be grabbed and removed if the dying unit is removed from the game? Btw, those triggers run several times per game, probably near 100. Would it be best to set a variable to the position of the dying unit and then make each location at the position of that variable, disposing of the variable afterwards? Quote:
You mean that every time a unit is created, not just a unit-group, I should destroy the last created unit group? That would probably be the cause of a lot of my lag issues with my respawn triggers, but I remove the unit from the game after it dies, is that another way around this? Btw this makes me worry about my respawn trigger. does Random Point in Rect cause a memory leak? Janemba Respawn Events Unit - A unit owned by Neutral Hostile Dies Conditions (Unit-type of (Dying unit)) Equal to Mini Janemba Actions Wait 60.00 seconds Unit - Create 1 (Unit-type of (Dying unit)) for Neutral Hostile at (Random point in JellyBean <gen>) facing (Random angle) degrees I guess I could set a variable equal to (Random point in JellyBean <gen>) just after the Wait 60 seconds and destroy it after the create unit. Would there be any conflict with this if several units died simultaneously? |
| 08-16-2005, 10:44 AM | #6 |
The problem with the unit group leak is that the GUI action "create N units..." itself leaks a unit group. There are some ways to fix this. One is to destroy the last created unit group after the "create N units..." action. Instead of that, there's also a function that destroys the next unit group that's created, which you would use before the create units action. Third option you have is to siply use CreateUnitAtLoc() function instead of the leaky GUI action. As far as removing dying units goes, they get removed from memory automatically when their corpse decays, and if the unit leaves no corpse, if it's a summoned unit or if it gets killed by an artillery attack, then it gets removed from memory right away. So, decreasing corpse decay time would be enough to decrease memory used by dead units, you wouldn't need triggers for that then. The trigger you posted now leaks as well, yes, 4 location objects whenever it runs. I think you got the solution right: at the start of the trigger, create a single location object by seting it to a variable, then use that object (by using the variable) throughout the trigger and in the end, destroy the object. It's importnat that you fix the critical leaks. Start with triggers that run often and with triggers that have loops. As I said, this last trigger you posted leaked 4 location objects and 4 unit group objects, the trigger you posted first leaked 70 objects alltogether. So, unless the second trigger ran much more often than the first, the first one is much more critical. There's no point in fixing triggers that leak 10 objects in the course of one game, focus first on the critical ones. |
| 08-16-2005, 10:58 AM | #7 |
I'm guessing this would be the correct leak free version of that trigger? DumDeath Copy 8 Events Unit - A unit Dies Conditions (Unit-type of (Dying unit)) Equal to Masenko Target Actions Set DeadDummyRect[(Player number of (Triggering player))] = (Position of (Dying unit)) Unit - Create 1 mesenko blast for (Owner of (Triggering unit)) at DeadDummyRect[(Player number of (Triggering player))] facing Default building facing (270.0) degrees Unit Group - Destroy unit group (Last created unit group) Unit - Create 1 mesenko blast2 for (Owner of (Triggering unit)) at DeadDummyRect[(Player number of (Triggering player))] facing Default building facing (270.0) degrees Unit Group - Destroy unit group (Last created unit group) Unit - Create 1 mesenko blast3 for (Owner of (Triggering unit)) at DeadDummyRect[(Player number of (Triggering player))] facing Default building facing (270.0) degrees Unit Group - Destroy unit group (Last created unit group) Unit - Create 1 mesenko blast4 for (Owner of (Triggering unit)) at DeadDummyRect[(Player number of (Triggering player))] facing Default building facing (270.0) degrees Unit Group - Destroy unit group (Last created unit group) Point - Remove DeadDummyRect[(Player number of (Triggering player))] Btw, back to the Unit respawn triggers, does the random point in rect location leak as well? Because the respawn triggers are probably the most used triggers in the map, so what would be the best of way of de-leaking this: Janemba Respawn Events Unit - A unit owned by Neutral Hostile Dies Conditions (Unit-type of (Dying unit)) Equal to Mini Janemba Actions Wait 60.00 seconds Unit - Create 1 (Unit-type of (Dying unit)) for Neutral Hostile at (Random point in JellyBean <gen>) facing (Random angle) degrees |
| 08-16-2005, 11:17 AM | #8 |
just like you have done with the others, clean the point leak and the unit group leak and you're done. |
| 08-16-2005, 11:58 AM | #9 | |
Quote:
Wouldn't optimizing the map remove the GUI and convert it over to CreateUnitAtLoc(), automatically removing the leaks? |
| 08-16-2005, 02:36 PM | #10 |
First of all, there's no GUI in the map, when a map gets saved all it's GUI gets converted to JASS so the map can actually be run by the game. Now, I don't know what your optimizer does, maybe it looks for common stupid functions like this and replaces them, maybe it doesn't. The most certain thing to do in any event is to just use the CreateUnitAtLoc anyway. |
| 08-16-2005, 07:12 PM | #11 |
so CreateUnitsAtLoc() will prevent the unit group leak that GUI causes, but what about the location leak? |
| 08-16-2005, 08:24 PM | #12 |
Hopefully u don't have cameras inside, coz applying cameras oftenly to a character will cause memory leaks too! If you make a custom spell that has loops it's best not to, it's better to make the trigger Longer and then make it local(this is if your planning to make effects) If your applying camera's, just set it's adjustment into apply camera properties instead of apply camera (Gen). |
| 08-16-2005, 08:48 PM | #13 | |
Quote:
No, I dont set cameras, so thats not a problem... I Just need to know if the CreateUnitsAtLoc() will still cause a location leak. |
| 08-16-2005, 10:06 PM | #14 | |
Quote:
First of all, it's CreateUnitAtLoc(), without the "s". Second, no, this function doesn't cause a location leak. However, it does require you to specify a location. If you specify the location with another funtion, like center of rect or position of unit, that function will then create an unreferenced location object which will leak. However, if you already use this location function before the create unit function and set the location it creates for you to a variable, then that location now is referenced (it has a variable pointing to it) and you can now use it in the create unit function as well as in a RemoveLocation() function afterwards to remove it. |
| 08-17-2005, 01:19 AM | #15 |
Thanks anitarf, I'm pretty sure that clears things up for me. Btw, theres a website for detecting memory leaks. Its at http://wc3onlinetools.wc.funpic.de/leak_indicator/index.php The only problem with it is, it doesn't seem to pick up most location leaks, like Position of (triggering unit), which is never detected as a leak from what I see. Nope, the leaks still seem to be there. A lot of people that play my map crash out of it with a critical error that says "Not enough storage is available to process this command." I put an action to destroy unit group after EVERY unit and unit group created, I destroyed every point variable at the end of the trigger, still a million leaks. I checked to see how the GUI was converted after optimization. This: Unit - Create 1 Cell Junior 5 for Neutral Hostile at JellyPoint[16] facing (Random angle) degrees Became This: call CreateNUnitsAtLoc(1,'n00X',Player(12),udg_JellyPoint[16],GetRandomReal(0,360)) I'm guessing that is why the unit group leaks, because it does a CreateNUNITS instead of CreateNUNIT (no 's'). However the function contains this: call CreateNUnitsAtLoc(1,'n00X',Player(12),udg_JellyPoint[16],GetRandomReal(0,360)) call DestroyGroup(GetLastCreatedGroup()) Not really sure why I'm still leaking then, if I picked them all up. |
