Memory leak writing string to file AS3 - actionscript-3

Using the windows process explorer I can see that memory in my program goes up, then gets collected and drops back down in a constant loop until I uncomment the following function:
protected function marker( output:FileStream, file:File, i:int, j:int ):void
{
output.open( file, FileMode.APPEND );
output.writeUTFBytes( i + "\t" + j + "\n" );
output.close();
}
With this function being called, the memory increases unboundedly until it reaches around 2GB and the whole thing crashes with an out of memory error. I was hoping someone could shed some light on where the leak here is and how to fix it, since I would like to be able to call this function reasonably frequently. Thanks. I think it's creating a new String each time but don't know why it's not being collected if this is in fact what's happening.

Related

Correct C Syntax for Function moved to RAM

I have a function that resides in flash memory but must run from ram.
Since it is not used often, I do not want the linker to relocate it.
Every thing is relative addressing so I can move it my self.
I'm using gcc for ARM and can't get the syntax correct in assigning the ram location to the ram based function pointer - please help
This is the function in flash:
byte Flash_Function(byte)
{
... code
}
These are global RAM variables
// pointer to ram based function .. called from flash based routines
byte (*Ram_Based_Routine)(byte) = 0; // issue is assigning a value to this
// XXX holds enought space to have routine copied into it
byte Ram_PlaceHolder_For_Function[XXX];
There is a function that does moves the function "Flash_Function" into the array "Ram_PlaceHolder_For_Function" and initializes Ram_Based_Routine pointer
I can't get syntax correct on this assignment line
Ram_Based_Routine = (*Flash_Function(byte))(Ram_PlaceHolder_For_Function);
if I were assigning the flash function -- this would be fine
Ram_Based_Routine = &Flash_Function;
So -- how to cast Ram_PlaceHolder_For_Function into Flash_Function?
Thanks for any comments

How much memory does Tcl_Obj* consumed , do i need to delete it?

std::string cmd = get_itcl_obj_name() + " set_ude_jobname " + name;
Tcl_Obj* cmdobj = Tcl_NewStringObj(cmd.c_str(),-1 );
if(Tcl_EvalObjEx(interp, cmdobj, TCL_EVAL_GLOBAL) == TCL_OK)
{
return true;
}
else
{
return false;
}
I have this part of code which is called thousands of time and consuming high memory, so i am not able to decide if this tcl object pointer needs to be deleted?
A Tcl_Obj points to a piece of memory that is 24 bytes long on a 32-bit system (I've not measured on 64-bit systems, but it could be up to 48 bytes, depending on how the compiler packs the structure). It can also point to further memory that can be variable in size; gigabytes is most certainly possible on 64-bit systems. In particular, the string representation of the value can be hanging off it, as can other things like list or dictionary representations. (The details are very variable under the covers.)
So yes, they should be released properly once no longer needed! While you never need to do that at the Tcl language level (other than by using unset on global variables occasionally) it's vital that you get the reference count management correct at the Tcl C API level.
In the specific case of the code you're working with, you need to both Tcl_IncrRefCount(cmdobj) before the call to Tcl_EvalObjEx and Tcl_DecrRefCount(cmdobj) after it. Since you're using C++, a helper RAII class might make this easier.
Or you could use Tcl_GlobalEval, which these days is just a wrapper around the same underlying basic function but does the Tcl_Obj memory management for you.
std::string cmd = get_itcl_obj_name() + " set_ude_jobname " + name;
if (Tcl_GlobalEval(interp, cmd.c_str()) == TCL_OK) {
return true;
} else {
return false;
}
(There are some minor performance differences, but they really don't matter. Or if they did, we'd advise a more substantial rewrite to use Tcl_EvalObjv, but that's a much larger change. Either that or maybe to do some caching of the Tcl_Obj so that Tcl can hang a bytecode compilation off the back-end of it usefully. All of which are quite a lot larger changes than you've got in mind!)

Running AS3 Function Asynchronously

I'm having a bit of trouble making sense of some of the tutorials for this online, thus why I'm asking here. (Using ActionScript 3, Adobe AIR, and Flash Professional CS5.5)
I have a very heavy function in my AS3 document class that I need to run asynchronously, so it doesn't stop the code on the MovieClip itself (don't ask me why, it just needs to be that way.)
So, simply put, how do I run this document class function (StartNow) asynchronously? The code can be placed in the document class or on the movieclip, I don't care where. It seems to be a relatively simple and common practice, but all my research is digging up nothing.
Thanks!
If your target is Flash player 11.4, there are Worker objects which can be assigned such a heavy function. I had no FP11, and eventually made a procedural generator that lasted more than 300 seconds per iteration in total. I had to use a state-based approach, paired with an enter frame listener. In my c ase, the entire complex generation process was split into logical chunks that were small enough to be completed within a reasonable timespan, and had a variable tracking the current generation phase. So, when another frame called the generation function, it read last completed step from that variable, performed one extra step with its set of data, stored the new value and exited for the frame. This, as is, is not a pure asynchronous process, but a pseudo-multitasking approach, this can suit you if your function that makes your SWF lag is splittable.
In Flash there is no such thing as run a function asynchronously, you have to do it yourself, unless you want to use Workers (like Vesper said). Workers gives you a separate process. Otherwise, you have to break your calculation into parts. This is how you do it:
Imaging 'trace' is a very heavy operation. It's not, but just to illustrate. This simple for-loop is runned on a frame, and causes a lower framerate, since it's all calculated before the frame actually renders.
for(var i:int = 0; i < 1000; i ++)
{
trace(i); // heavy calculation here
}
So you have to break the calculation into parts, and break it to be able to run the calculation over time.
To do that, you have to create a function which just takes a part of the loop every time:
calculatePart(0, 1000, 20);
function calculatePart(startIndex:int, endIndex:int, amountPerRun:int)
{
for(var i:int = startIndex; (i < startIndex + amountPerRun) || (i < endIndex); i ++)
{
trace(i); // heavy calculation here
}
if (i < endIndex)
{
calculatePart(i, endIndex, amountPerRun);
}
}
This is actually the same function as the simple for-loop in the first code, it also outputs 1000 traces. It is prepared to run in parts, but this isn't async yet. We can now change the function easily, so the function operates over time.
I use the setTimeout for this. You can also use a ENTER_FRAME event-listener or the Timer class for this, but for the sake of this example I try to keep it clear.
calculatePart(0, 1000, 20, 100);
function calculatePart(startIndex:int, endIndex:int, amountPerRun:int, timeBeforeNextRun:Number)
{
for(var i:int = startIndex; (i < startIndex + amountPerRun) && (i < endIndex); i ++)
{
trace(i); // heavy calculation here
}
if (i < endIndex)
{
setTimeout(calculatePart, timeBeforeNextRun, i, endIndex, amountPerRun, timeBeforeNextRun);
}
}
As you can see, I've added a timeBeforeNextRun parameter. If you run the example, you can see it takes 100 milliseconds before 20 traces are outputted.
If you set it very low, the calculation will be tried to be done very fast, however you cannot gain extra speed just by trying to do more in less time of course. You have to play with the time and amount variables, you can test which one actually gives better performance (or less lag).
// more time between a run, less calculations per run
calculatePart(0, 1000, 30, 10);
// more calculations per run, more time between a run
calculatePart(0, 1000, 100, 30);
Hope this helps.
If you want to use a smarter calculation of the time, I found this utility class very helpful, which measures how much time the calculation actually took, and alter the time itself.

Time Slow/Speed Up Power Up

I'm creating a collecting game, and I want to create a time slow/speed up powerup.
Any ideas on how to do that in Flash/AS3?
One way I thought of was simply changing the frame rate. I can slow down the frame rate. But when I try to increase the frame rate beyond 60, Flash caps it at 60.
Thank you in advance for your help.
I like to do time-based movement instead of frame-based movement for better consistency. The general concept is to check the amount of time passed between frames and base movement on that instead of frames which can alternate (e.g. you can have 60FPS for a bit and then it slows down to 30FPS). You can do a simple calculation based on time passed for movement, for instance player.x += player.speed * timeDiff but that can result in odd situations if the time passed between frames happens to be really large (for instance, the player can end up missing lots of collisions since you are moving him in one large movement). Instead, I like to use a game loop to move the player X times based on the amount of time that has passed between frames, ensuring that collisions and any other game loop events will be properly checked.
This also has the advantage that it is easy to adjust the speed.
Here is the basic concept:
private var speedMultiplier:int = 100;//100 normal speed, 0 paused
private var currRealTime:int = getTimer();
private var currGameTime:int = currRealTime;
private var globalLastTime:int = currRealTime;
private var totalTimeDiffRemainder:int = 0;
private var loopTime:int = 20;//every 20 ms run our actions
public function getGameTimer():int
{
return currGameTime;
}
private function updateGameTime():void
{
var realTime:int = getTimer();
currGameTime = currGameTime + speedMultiplier/100*(realTime - currRealTime);
currRealTime = realTime;
}
private function runEvents(event:Event):void
{//ENTER_FRAME event
var totalTimeDiff:int = getGameTimer() - globalLastTime + totalTimeDiffRemainder;
globalLastTime = getGameTimer();
while (totalTimeDiff > loopTime)
{//every 20 ms run all our actions
totalTimeDiff -= loopTime;
//run all your game loop events here, such as collision checks
}
totalTimeDiffRemainder = totalTimeDiff;
updateGameTime();
}
So every time an ENTER_FRAME event fires, we will check the time passed since the last ENTER_FRAME event and then run our actions once for each 20ms that has elapsed and pass the remainder over to the next ENTER_FRAME event. For instance, if it's been 47 ms since the last ENTER_FRAME, we will run our actions twice and pass over 7 remaining ms to the next ENTER_FRAME event.
In order to pause, slow down, or speed up the game, all you have to do is modify speedMultiplier. Changing speedMultiplier to 0 will pause the game, 50 is half speed 100 is normal speed, 200 double speed, etc.
I believe the general way to do this would be to use an MVC like setup where your model holds all the data for the game elements (character position/orientation, enemies, dynamic map elements) then the controller is modifying the model. With the controller modifying the model this way you could add a multiplier to the model, and use the multiplier when having the controller update the model for "physics" or other modifying dynamic elements in the game.
Roughly:
Model
public var speedMultiplier:Number=1;
public var playerXSpeed:Number;
public var playerYSpeed:Number;
Controller (I'm assuming you make a controller class and pass the view to the constructor and are listening for events from the view in the controller).
private function enterFrame_handler(event:Event):void
{
var playerSprite:Sprite = mainView.playerSprite;
playerSprite.x += playerXSpeed*speedMultiplier; //only problem I can see here is your player skipping past certain elements, to avoid this you could use a loop to make each motion and do checks but it's more CPU intensive
//var enemySprites:Vector<EnemySprite>;
//other game physics here, reduce speed due to drag, fix any invalid values etc.
}
Edit
Actually in thinking this through some more, although I do generally like using an MVC setup myself since it allows one to have a single sprite that does all the drawing; you could also use the same concept of a speedMultiplier shown here without necessarily changing around any software patterns. If you end up needing to do it with a loop because you need it to do checks for every spot it would hit as an object moves along, you may need to have your default speedMultiplier be something like 10 so you could set it down to 1 to get 1/10th speed with all the same checks as it would get at 10 being normal speed (again only issue here being it has to do whatever calculations 10 times for every update, in this case you may want to use a timer instead of the frame rate to control the overall calculation speed).

Starting many Timers at the same time in AS3

var LevelCode:Array = [10,20,30,40,50,60,70,80,...,990,1000];
var Piece0:Timer = new Timer(50, LevelCode[0]);
var Piece1:Timer = new Timer(50, LevelCode[1]);
...
var Piece98:Timer = new Timer(50, LevelCode[98]);
var Piece99:Timer = new Timer(50, LevelCode[99]);
I want to start Piece0 timer, Piece1 timer, etc., at the same time.
I tried Piece0+Piece1.start();, but it did not work.
Can you guys help me?
maybe you don't need many timers, since you're using identical 50 milliseconds timers.
why don't you just use one timer and handle the event int the function specified with addEventListener?
var myTimer:Timer = new Timer(50);
myTimer.addEventListener(TimerEvent.TIMER, timerElapsed);
myTimer.start();
function timerElapsed(event:TimerEvent):void
{
//handle your levels here
}
Running
Piece0.start();
Piece1.start();
Will start them near enough to the same time as to be beneath the threshold that they can resolve, so they'll be effectively the same time. Starting a timer is not a resource-intensive process.
You can not rely on timers triggering at the same time like this.
This is a very bad implementation and you need to think about a redesign.
ActionScript is not threaded and as such is asynchronous.
Because of this no two timer events will ever fire at the same time.
It will always be one after the other. You should follow the suggestion that vulkanino had made and consolidate everything into one call.
Plus having 100+ timer events is a lot of over head and can you be certain all 100 timer events would be processed in the 50 milliseconds you are giving them to run?
If not you risk some "overlapping issues" all dependent on the code you are doing in the callback functions.