| 05-04-2004, 11:21 PM | #1 |
After doing a search of the forum, I came across several discussions of what causes memory leaks and a lot of Jass functions, but unfortunately, I am not a very Jass-orientated person so much of the meaning eluded me. I was wondering if anyone could give me a action that will help stop memory leak from special effects and creating units. Also, please explain in a way that someone who is experienced with GUI, and knows some basic Jass could understand. Thanks in advanced! |
| 05-05-2004, 01:00 AM | #2 |
Well, the reason memory leaks are discussed so much in relations to JASS functions...is that it's easier to explain and understand them in JASS, as then you are working on a level which is closer to what truly is happening in triggers. But to explain on a simple level... Memory Leaks are leakage of handle objects...that is...all objects excluding: Integers (including: Unit-Types, Item-Type and AbilityID), Reals, Booleans and Strings. However, the only leak we should be concerned with, are the leakage of objects you dynamically create...that is...objects that get temporarely created in-game. So no need to worry about pre-placed units, regions, triggers, players, bleh. You mostly need to worry about two object-types...these are: Unit Groups... and Locations. Now, the thing is... EVERY time...in the Trigger Editor...when you are making an action...and you open up one of those GUI window labeled "Point"...and select something in it "except" a variable... that point will then "leak". That is... it will create a point for you, and as you're not keeping track of this new point, it will then go out of reach, and it will thus ... leak. Same lies with Unit Groups, all the actions in that GUI window, except the "Last Created Unit Group" one, will leak the unit-group they create. These are the 2 most serious things, as they are the type you use the most. Player Groups are also created a few times, but not as often. However, they can be handled using the same way as mentioned further down. And then there are the temporary Units and Special Effects one creates. And to a even lesser extent, one sometime creates Regions, Timers, Timer Dialog Windows, Temporary Dialog Windows, Temporary Multiboards, Temporary LeaderBoards, Floating Texts, Sounds and Visibility Moderators. But most of these are way to rare to care about. And there is a certain rule of thumb, if the trigger runs only once (or just rarely), you don't need to worry about it.. But if it's a common trigger, like a periodic event, or something big....or if you're Looping alot, then you should go through it and cover up all memory leaks in it. So, basicly, Blizzard gave us a bunch of functions to destroy these created objects...but unfortunately, they didn't add them to GUI :P. So basicly, you have 2 options... You can either; * Use Custom Script actions to use the Blizzard natives in JASS, or... * Get WEU or UMSWE...as they have these actions included in GUI And what you do...is first, you create 1-2 Point variables named something like: TempPoint, and a Unit Group variable named similarely... Then, whenever you see yourself selecting something from a Point window or a Unit Group window except in a "Set Variable" action... you have to instead do the following: Code:
Set TempPoint = (Center of UnitSpawn <gen>) Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees Custom script: call RemoveLocation( udg_TempPoint ) So you can basicly see that I moved the "(Center of UnitSpawn)" action, to a "Set Variable" action. Then after using it, you destroy it. Note, that in UMSWE, it would look like the following: Code:
Set TempPoint = (Center of UnitSpawn <gen>) Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing (270.0) degrees Point - Remove TempPoint This works the same for Unit Groups and Player Groups. Except you change the last line too (if you're using the Custom Script action): Custom script: call DestroyGroup( udg_TempGroup ) and Custom script: call DestroyForce( udg_TempForce ) //Force = Player Group UMSWE and WEU have both of these actions. Now, the same thing is needed for "Temporary Units" and Special Effect, and luckily, WE has a action for destroying these. Depending on wether there is a Wait action between the point where you create your special effect, and where you want to destroy it...you can set "Last Created Special Effect" in a special effect variable, then just use: Special Effect - Destroy TempSFX You can also just use that action on "Last Created Special Effect" if there is no wait involved (but I guess that's rare). Note, that...eh, since two triggers could be using the same SFX variable at the same time...you should try to either have a controlled access to these variables....or better...derive Local variables for you to use. That's something I won't cover in this post. But yeah, Destroy Units work the same way. To be safe, you might wanna first Kill the unit, then Destroy it, as there have been problems at Destroying units directly in certain situations (if it's hidden f.ex.). And for all the other types I mentioned above...in most of the cases there is a GUI action for destroying it. Fhew, this message has gotten long. Anyhow, one last tip. In triggers that run only once, you can add to the end of it the following action to destroy it, people have reported that it's quite effective. Trigger - Destroy (This trigger) EDIT: I have realized that this GUI action is only available in UMSWE/WeU, if you don't have it, or don't want it, simply use this action: Custom Script: "call DestroyTrigger(GetTriggeringTrigger())" It works in any trigger. Anyhow, that's it. Cubasis |
| 05-05-2004, 01:49 AM | #3 |
I think you left off a page... :) Thanks Cubasis, I knew most of that, but I never used the destroy trigger before. In fact, I barely knew it exsisted... Hrmm... Thanks again. |
| 05-05-2004, 01:34 PM | #4 |
Sw33t gu1d3 Cubasis :) I am going to use it right away ^^ Only one question, though. Is there any tutorial from which i can learn when are objects dynamically created? Just to know when and what to clean up :) |
| 05-05-2004, 06:55 PM | #5 |
Erhm, well, for all the types I mentioned in my other post, when you open a GUI window with the title of that type... Then most of the time it will be creating a new object for you of that type. As I said, it's easyer to understand this in JASS, but that's the general rule of thumb. There are only a couple of exceptions where Blizzard returns a global object that it stores/uses behind the scenes, that you should not destroy. For Example "Playable Map Rect" etc. But these are not many, and in most cases, you're getting a fresh object that you need to get rid off. But note, I say by experience, that... the most serious offenders are Unit Groups, and Locations. If you get rid of all those kind of leaks in common triggers in your map, exit-time should be near-instant (a few seconds at most) - Much better than 30-120 seconds as one sometimes experiences after a long session of playing a Battle.Net TD map. Cubasis |
| 05-05-2004, 09:31 PM | #6 |
Hmm. Some people on mIRC say they still leak even if you set the objects directly into variables. Any truth to that? |
| 05-05-2004, 11:12 PM | #7 |
I have a question for Cubasis, should any of these triggers be destroyed and if so how? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P1 Spawn Loop Events Time - Every 0.50 seconds of game time Conditions ((Entering unit) is A structure) Equal to False Actions Unit Group - Pick every unit in (Units in P1 Spawn enter <gen>) and do (Actions) Loop - Actions Unit - Create 1 (Unit-type of (Picked unit)) for Player 1 (Red) at (Center of P1 Spawn exit <gen>) facing Default building facing degrees ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P1 Spawn Stop Events Player - Player 1 (Red)'s Food used becomes Greater than or equal to 100.00 Conditions ((Entering unit) is A structure) Equal to False Actions Trigger - Turn off P1 Spawn Loop <gen> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P1 Spawn Restart Events Player - Player 1 (Red)'s Food used becomes Less than 100.00 Conditions Actions Trigger - Turn on P1 Spawn Loop <gen> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P1 Naga Buildings Events Dialog - A dialog button is clicked for P1RaceSelector Conditions (Clicked dialog button) Equal to P1Naga Actions Unit - Create 1 Shrine of Azshara for Player 1 (Red) at (Center of P1 Building 6 <gen>) facing Default building facing degrees Unit - Create 1 Spawning Grounds for Player 1 (Red) at (Center of P1 Building 5 <gen>) facing Default building facing degrees Unit - Create 1 Temple of Tides for Player 1 (Red) at (Center of P1 Building 2 <gen>) facing Default building facing degrees ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ also, what a about these little command triggers? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P1 Kill Events Player - Player 1 (Red) types a chat message containing -kill as An exact match Conditions Actions Unit Group - Pick every unit in (Units currently selected by Player 1 (Red)) and do (If ((Owner of (Picked unit)) Equal to Player 1 (Red)) then do (Unit - Explode (Picked unit)) else do (Do nothing)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Display Unit Type Information Events Player - Player 1 (Red) types a chat message containing -type as An exact match Conditions Actions Unit Group - Pick every unit in (Units currently selected by Player 1 (Red)) and do (Game - Display to Player Group - Player 1 (Red) the text: (String((Unit-type of (Picked unit))))) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ thanks for your help. |
| 05-06-2004, 12:18 AM | #8 |
ThyFlame, depends. Ofcourse it's not enough "just to capture it into a variable", that's just half the deal, you then ofcourse need to Destroy the object inside the variable when you're done using it. However, if they still said that wasn't enough, then either they're either misunderstanding something, or they're talking about (or confusing it with) local variables. That's another level of leaks you fight there, and is only a concern if you're using local variables,...so the thing I explained in my post above will work 100% for a GUI user. If you are using JASS, I may write sometime later a post about the local-variable leaks. Which are really simple to counter, just a little hard to understand (which ofcourse you don't really need to). Sweet5, as I said, you should only destroy triggers that run only once during the game, and that you don't need to use any more (ever). Without looking thoroughly through your triggers, they all look like they are periodic/common triggers that need to run often through out the game. You yourself need to be the judge of what triggers you don't need anymore and stuff. And generally, it's pretty simple. Don't be too paranoid about this, as this is just a slight memory-bonus for perfectionists, wether you destroy that one extra trigger or not does not change anything critical in-game. In my own map, I only destroy my Init Triggers and the Cinematic triggers (when they're done). Cubasis |
| 05-06-2004, 12:25 AM | #9 |
thanks cubasis, in that case I would just like to know how to delete this one trigger, it only occurs once at the beging of the game. P1 Naga Buildings Events Dialog - A dialog button is clicked for P1RaceSelector Conditions (Clicked dialog button) Equal to P1Naga Actions Unit - Create 1 Shrine of Azshara for Player 1 (Red) at (Center of P1 Building 6 <gen>) facing Default building facing degrees Unit - Create 1 Spawning Grounds for Player 1 (Red) at (Center of P1 Building 5 <gen>) facing Default building facing degrees Unit - Create 1 Temple of Tides for Player 1 (Red) at (Center of P1 Building 2 <gen>) facing Default building facing degrees |
| 05-06-2004, 12:29 AM | #10 |
EDIT.... sorry, my bad. Here: I have realized that this GUI action is only available in UMSWE, if you don't have it, or don't want it, simply use this action: Custom Script: "call DestroyTrigger(GetTriggeringTrigger())" It works in any trigger. So yeah, just put that in the end of your trigger that you want to destroy. ~Cubasis |
| 05-06-2004, 01:30 AM | #11 |
I have a quick question about local variables. At the moment I have some dummy casters set to a local variable then at the end I explode them and set the local to null, does this leak? |
| 05-06-2004, 02:04 AM | #12 |
No, but I believe remove unit is a more perferred method. Exploding creates a special effect, which is cleaned up true, but still it temporarily uses more memory then when using remove. |
| 05-06-2004, 02:13 AM | #13 |
Yeah but I thought using removing a unit leaked, I never understood why though. I mean if its out of the game for good why the hell would it remain in memory? Also exploding a unit doesnt cause any special effect when I do it. I wasnt sure about it so I removed every exploded unit's Art - Special. Edit: Oh yeah I forgot to ask, what I should do with Sounds and Timers that are used throught a game? |
| 05-06-2004, 02:49 AM | #14 |
It does create an effect even if you don't use a graphic. Anyway remove is less memory costly its been proven in some other thread. Destroy Timers and Destroy Sounds when done simple as that. A simple rule to live by: If your not using it, destroy it. (primitives or strings are exceptions to this rule because they can't be destroyed). |
| 05-06-2004, 03:47 AM | #15 |
So exploding creates an effect that I cant see or pick up in triggers? o_O :> Anyways the Sounds and Timers Im using are used several times. I forgot(I dunno why) that you could set the sounds to a variable at the start and use them that way. Im gonna have experiment with Timers for a while the way you said, cuz I really just started using them today. Thanks weaaddar |
