If I have something like the following:
myObj = new THREE.Object3d;
scene.add(myObj);
doIt();
function doIt(){
var geometry = new THREE.SphereGeometry( 1, 8, 8 );
var mesh = new THREE.Mesh( geometry, meshMaterial );
myObj.add(mesh);
}
as far as I understand, the variables geometry and mesh get unassigned as soon as the function concludes. But the scene object still contains myObj, which still contains the mesh, which still contains the geometry. So now the geometry lives within myObj within scene. Am I getting it right so far?
But if I then do
scene.remove(myObj);
and also
myObj = new Object();
Then I would think there is no more mesh, no more geometry. I no longer have any extant variable or object which contains or refers to those things. But they still exist somewhere, taking up memory?
There is a dispose() function in three.js, but I don't understand where in my sequence of code it should be normally applied, or exactly why?
I am working on a project which needs to create and then remove lots of objects, so I'm afraid if I don't do it right, there will be performance issues.
Any wisdom much appreciated.
In javascript, objects exist in memory until they are cleared out by it's garbage collector. By assigning a new object to the variable, you are basically just creating a new variable with the same name. The old data still exists in memory until the garbage collector runs and removes the old data from memory.
Since JavaScript's memory is only cleared out by the garbage collector, and you can't manually trigger a garbage collection (and you shouldn't have to), you should use object pooling instead of creating a ton of disposable objects.
Note: This doesn't mean you should always use object pooling, but rather, you should use an object pool if you find yourself creating and dereferencing a large number of objects within a short time span.
Remember, don't optimize prematurely.
In simple terms, object pooling is the process of retaining a set of unused objects which share a type. When you need a new object for your code, rather than allocating a new one from the system Memory Heap, you instead recycle one of the unused objects from the pool. Once the external code is done with the object, rather than releasing it to main memory, it is returned to the pool. Because the object is never dereferenced (aka deleted) from code it won’t be garbage collected. Utilizing object pools puts control of memory back in the hands of the programmer, reducing the influence of the garbage collector on performance.
source
You can find various object pool boilerplates online, but here's an example: https://gist.github.com/louisstow/5609992
Note: there's no reason to keep a large pool of excess objects in memory if you are no longer creating a large amount of objects. You should reduce the pool size, freeing the unused objects, and allowing the GC to collect them. You can always increase the size again if you need to. Just don't switch between shrinking and increasing the pool size too quickly, otherwise you would just be defeating the point of an object pool.
var objectPool = [];
var marker = 0;
var poolSize = 0;
//any old JavaScript object
function commonObject () { }
commonObject.create = function () {
if (marker >= poolSize) {
commonObject.expandPool(poolSize * 2);
}
var obj = objectPool[marker++];
obj.index = marker - 1;
obj.constructor.apply(obj, arguments);
return obj;
}
//push new objects onto the pool
commonObject.expandPool = function (newSize) {
for (var i = 0; i < newSize - poolSize; ++i) {
objectPool.push(new commonObject());
}
poolSize = newSize;
}
//swap it with the last available object
commonObject.prototype.destroy = function () {
marker--;
var end = objectPool[marker];
var endIndex = end.index;
objectPool[marker] = this;
objectPool[this.index] = end;
end.index = this.index;
this.index = endIndex;
}
//make this as big as you think you need
commonObject.expandPool(1000);
Related
Hellooooo, hope y'all are doing great.
A while ago, I asked a question about how to do particle explosions in AS3 when I was coming from AS2. Luckily, I got help from Organis (thank you so much btw), but every time I try export the animation in SWF, it keeps crashing my file and I'm not sure why?
I should probably preface that what I'm doing is specifically for animation. I'm not trying to make a game, just a simple script where the movieclip I created can explode into different objects in its timeline...if that made any sense.
In case anyone needs the actual file itself, you can download it right here: https://sta.sh/018lqswjfmp2
Here is the AS2 version in case anyone needs it: https://sta.sh/02fzsqon3ohw
Here is the code given to me by Organis:
// Allows the script to interact with the Particle class.
import Particle;
// Number of particles.
var maxparticles:int = 200;
// I imagine you will need to access the particles somehow
// in order to manipulate them, you'd better put them into
// an Array to do so rather then address them by their names.
var Plist:Array = new Array;
// Counter, for "while" loop.
var i:int = 0;
// The loop.
while (i < maxparticles)
{
// Let's create a new particle.
// That's how it is done in AS3.
var P:Particle = new Particle;
// The unique name for the new particle. Whatever you want it for.
P.name = "particle" + i;
// Enlist the newly created particle.
Plist.push(P);
// At the moment, the P exists but is not yet attached to the display list
// (or to anything). It's a new concept, there wasn't such thing in AS2.
// Let's make it a part of the display list so that we can see it.
addChild(P);
i++;
}
And in case anyone needs it, here is the code I used for AS2:
maxparticles = 200; //number of particles
i = 0; //counter, for "while" loop
while(i < maxparticles){
newparticlename = "particle" + i; //creates a new name for a new particle instance
particle.duplicateMovieClip(newparticlename, i); //duplicates our particle mc
i++;
}
I am using kotlin in combination with lwjgl. So far I had the following code that ran several thousand times per second:
// val textureMap = HashMap<Int, Texture>()
fun bind() {
var index = 0
for(entry in textureMap) {
glActiveTexture(GL_TEXTURE0 + index)
entry.value.bind()
program.setInt(entry.key, index)
++index
}
}
So while this was running absolutely fast and consumed virtually 0 of my frame time as expected I had to replace it because it created an Iterator in every call, eventually leading to tens of thousands of those objects eventually getting garbage collected and halting my program for a few milliseconds which is of course not usable in my application.
So I went ahead and changed it to the following code:
// textures = ArrayList<Texture>()
// indices = ArrayList<Int>()
fun bind() {
var index = 0
while(index < textures.size) {
val uniform = indices[index]
val texture = textures[index]
glActiveTexture(GL_TEXTURE0 + index)
texture.bind()
program.setInt(uniform, index)
++index
}
}
Now for some reason I am noticing a massive drop in performance, namely the function now uses several seconds per frame. Using jvisualvm I was able to determine that all that time is spent in glActiveTexture in the native part as well as the native function in program.setInt(...). I am absolutely stumped why this is the case, especially after comparing the byte code of the two.
This is the decompiled class file for the first (fast) version:
public final void bind()
{
int index = 0;
Map localMap = (Map)this.textureMap;
for (Map.Entry entry : localMap.entrySet())
{
GL13.glActiveTexture(33984 + index);
((Texture)entry.getValue()).bind(); Program
tmp66_63 = this.program;
if (tmp66_63 == null) {
Intrinsics.throwUninitializedPropertyAccessException("program");
}
tmp66_63.setInt(((Number)entry.getKey()).intValue(), index);
index++;
}
}
And that is the byte code of the slow version:
public final void bind()
{
int index = 0;
while (index < this.textures.size())
{
Integer uniform = (Integer)this.indices.get(index);
Texture texture = (Texture)this.textures.get(index);
GL13.glActiveTexture(33984 + index);
texture.bind(); Program
tmp52_49 = this.program;
if (tmp52_49 == null) {
Intrinsics.throwUninitializedPropertyAccessException("program");
}
Integer tmp62_61 = uniform;Intrinsics.checkExpressionValueIsNotNull(tmp62_61, "uniform");tmp52_49.setInt(tmp62_61.intValue(), index);
index++;
}
}
I am extremely confused what is going on here. In both versions the call to glActiveTexture is GL_TEXTURE0 + <an int value>, yet one takes so much more time thatn the other.
Does anyone have an idea what I am missing here?
Basically my entire question can be removed. I should have debugged and not only profiled. The problem was the code that populated the lists, and it didnt remove the old values so the lists grew larger and larger and the loop just ran so many more times over time...
In case anyone was wondering how I fixed my problem with the allocations I essentially created two collections, one is containing the uniforms and one is mapping them to textures. And then I can iterate over the uniforms and then get the respective texture. So no pointless Iterator objects are created but I am also not having any duplicates :)
so I was wondering if there was a way to reference different objects on stage with he same method to save repeating lots of lines of code. This is what I have right now
function bossKilled(i:Number):Void {
trace("Boss Killed!");
kills ++;
_root.bossDeath.gotoAndPlay(2);
_root["pirate"+i+"Active"] = false; //name of variable would be pirate1Active
_root["pirate"+(i+1)+"Active"] = true; //name of variable would be pirate2Active
bossDeath._x = _root["pirate"+i+"Active"]._x;
bossDeath._y = _root["pirate"+i+"Active"]._y; }
However, this reference does not actually affect the variables. I was wondering if this was possible, and if so, what am I doing wrong?
Thanks.
Not sure what you try to achieve ... pirate1Active is a BOOL. A BOOL has no _x or _y property (nor any other).
If you are not sure where to find your objects in the object tree, you can use the debugger or add some traces on the MCs timeline, like trace (_parent);
Consider switching to AS3, it is much more object oriented and has better tools support.
I am loading a mc called Spiri into a mc called Box. Later I want to remove both from memory usage and off screen. I have the off screen in a tween not shown here.
If I use removeChild(box); will it also remove all Children with in?
Basically I am loading 3 movies from library with a function call. Then trying to remove them and call the same function multiple times. Which means the same movies are loaded again and again with the same names. This IS SUPPOSED TO replace the old ones but maybe its not because I am not removing them properly because by the 10th or 15th call it is getting very slow.
I am also adding an event-listener in a function too. Is that then adding a some event-Listner every single time and taking up resources as well?
It seems to be very slow after several times running a that function which makes me believe something is not getting unloaded correctly.
//I tried
box.removeChild(Spiri);
Spiri = null;
//then remove the parent like this
removeChild(box); /// but this gets an error.
again if i just do this
removeChild(Spiri); // it makes me wondering if they are getting removed.
How what is the best way to remove parent and all children in an mc?
Yes and no. The children are no longer located on the stage, but they are still children to the parent until removeChild() is called. That can be good and bad. Obviously, it is great for reusing objects but can be terrible for memory management because those objects can only be garbage collected when their parent is garbage collected. For a simple app, that is usually fine. But for something massive... not so much.
For the project I am working on now (a massive 30 page, 50,000 liner), I created a light-weight GUI framework to handle all of my DisplayObjects. Everything except basic Bitmap and Shape DisplayObjects extend a single class which extends Sprite. In that class, I have this function:
final public function destroy():void {
this.removeAllEventListeners();
var i:int, l:int, cur:DisplayObject;
l = this.numChildren;
for ( i = 0; i < l; i++ ) {
cur = this.getChildAt( i );
if ( cur is XISprite && !this.stopChildXISpriteDestroy ) {
( cur as XISprite ).destroy();
}
else if ( cur is Sprite ) {
( cur as Sprite ).removeChildren();
}
if ( cur is Bitmap && ( cur as Bitmap ).bitmapData && !this.stopBitmapDestroy ) {
( cur as Bitmap ).bitmapData.dispose();
}
if ( cur is Loader && !this.stopLoaderDestroy ) {
( cur as Loader ).unload();
}
if ( cur is Shape ) {
( cur as Shape ).graphics.clear();
}
}
cur = null;
i = l = NaN;
this.removeChildren();
}
It basically does a hard wipe of all the objects and allows me to easily qualify all children of that class for Garbage Collection. I also am keeping track of all event listeners so there is no chance at all a rogue listener could prevent GC (by calling removeAllEventListeners()). I also have some protected flags in the class that allow you to stop the destroy on a certain object type (so I can leave a SWF or an image loaded in memory if needed)
It might be overkill, but memory consumption has been an issue in this app and that function has really helped manage it. This may be more than you need, so you can just call removeChildren() with default params and it will remove all children from the parent object.
As an afterhthought: Keep your DisplayObjectContainers as simple as possible. Avoid nesting them as often as possible. The first conditional, where I call destroy on every single XISprite that is a child of an XISprite is great but it could be disastrous if there were loads and loads of XISprite children as the destroy() calls would pile up on each other and freeze the app.
I admittedly know little about the inner workings of javascript, but need to make a library and would like to learn (hence asking here). I understand using the closure and exporting to window to not pollute the global namespace, but beyond that it confuses me a bit.
(function() {
var Drop = window.Drop = function() {
var files = [];
var add = function(word) {
files.push(word);
return files;
}
return {
files: files,
add: add
}
}
})()
// All of these seem to be the same?
var a = Drop();
var b = new Drop();
var c = new Drop;
// Each has their own state which is what I want.
a.add("file1");
b.add("file2");
c.add("file3");
Why are all three ways of "initializing" Drop the same?
What exactly gives them the ability to have their own state?
Is there an alternative to the return syntax to export those functions on Drop?
Is there just a flat out better best practice way of creating a self contained library like this?
I have searched around the net, but have found very little consistency on this subject.
The first way (Drop()) just calls the function as normal, so this is the global object (window in browser environments). It does its stuff and then returns an object, as you'd expect.
The second way (new Drop()) creates a new Drop object and executes the constructor with this set to that object. You do not, however, use this anywhere and return an object created from an object literal, so the Drop object is discarded and the object literal returned instead.
The third way (new Drop) is semantically the same as the second; it is only a syntactic difference.
They all have their own state because each time you call Drop, it has its own set of local variables distinct from the local variables of any other call to Drop.
You could transform your code to use the normal new syntax and prototypes. This has a few advantages: namely, you only create the add function once rather than one for each Drop call. Your modified code might look like this:
function Drop() {
this.files = [];
}
Drop.prototype.add = function(word) {
this.files.push(word);
return this.files;
};
By doing this, though, you lose being able to call it without new. There is, however, a workaround: You can add this as the first line inside function Drop:
if(!(this instanceof Drop)) {
return new Drop();
}
Since when you call it with new, this will be a Drop, and when you call it without new, this will be something other than a Drop, you can see if this is a Drop, and if it is, continue initializing; otherwise, reinvoke it with new.
There is also another semantic difference. Consider the following code:
var drop = new Drop();
var adder = drop.add;
adder(someFile);
Your code will work here. The prototype-based code will not, since this will be the global object, not drop. This, too, has a workaround: somewhere in your constructor, you can do this:
this.add = this.add.bind(this);
Of course, if your library's consumers are not going to pull the function out of the object, you won't need to do this. Furthermore, you might need to shim Function.prototype.bind for browsers that don't have it.
No. It's all a matter of taste.
Why are all three ways of "initializing" Drop the same?
// All of these seem to be the same?
var a = Drop();
var b = new Drop();
var c = new Drop;
When you use new in JavaScript to invoke a function, the value of this inside the function becomes the new object.
But the reason they're the same in your case is that you're not using this at all. You're making a separate object using object literal syntax, and returning it instead, so the new has no impact.
What exactly gives them the ability to have their own state?
Because each function invocation makes a new object, each object is entirely different for each invocation.
The functions assigned to the object are recreated in each Drop invocation, and therefore create a closure over the enclosing variable scope. As such, the files array of each invocation is continuously accessible to the functions made in each respective invocation.
Is there an alternative to the return syntax to export those functions on Drop?
Yes. Assign the functions and array to this, and remove the return statement. But that will require the use of new. Alternatively, put the functions on the .prototype object of Drop, and they'll be shared among all instances made using new, but keep the array assigned to this in the constructor so that it's not shared.
For the prototyped functions to reference the array, they would use this.files.
Is there just a flat out better best practice way of creating a self contained library like this?
JavaScript is very flexible. There are many ways to approach a single problem, each with its own advantages/disadvantages. Generally it'll boil down to taking advantage of closures, of prototypal inheritance, or some combination of both.
Here's a full prototypal inheritance version. Also, the outer (function() {})() isn't being used, so I'm going to add a variable to take advantage of it.
(function() {
var totalObjects = 0; // visible only to functions created in this scope
var Drop = window.Drop = function() {
this.files = [];
this.serialNumber = totalObjects++;
}
Drop.prototype.add = function(word) {
this.files.push(word);
return this.files;
};
})();