In my code I was to deleting custom-objects. I realized, we can not delete objects which are declared using 'var'. (after reading this documentation Delete operator).
Most of my objects are declared and initialized using 'var'. They can't be deleted in single delete statement(unless I loop through it and delete each property.)
I can set them to 'null'.
My custom objects are relatively bigger in size (may block considerable chunk of memory.
For better memory management and performance should I use 'properties' or 'variables' to store my objects? Will it make a difference?
Please provide any references for better insight on 'properties' and 'variables' in javascript.
globalProp = {//can be deleted, it is a 'property' to global object.
'name': 'Mia',
'age': 34,
'sex': 'F'
};
var globalVar = {//can not be deleted with delete statement, it is variable of global object
'name': 'Lia',
'age': 25,
'sex': 'F'
};
(In above code, we can refer to globalProp as 'window.globalProp' but can't refer to globalVar as window.globalVar.)
Have fiddle
JavaScript has runtime and garbage collector with some complex cleaning and managing algorithms, any try to interfere or speed them will proably do the opposite, resulting some runtime penalty. it is the best to leave the memory managment to the underlying runtime.
however, there are some points that you might want to consider:
1) avoid global variables as much as possible. this is a good advice for any language that support global/static variables. global variables means global references with no scope - the referenced object will live on as long as the (global) reference holds it. this danger increases even more if the global variable is an array or object which keeps on appending children to itself.
this is the common case which leads to a memory leak in managed languages
2) avoid cyclic references - don't make one member variable point to a different object, and that object holds a member which points to the first object. this will make a hard time for the garbage collector.
3) write clean, simple, maintainable code. this may seems as unrelated preach, but an easier, short, maintainable code will probably enhance the interperter/compiler ability to optimize the code.
4) don't assume nothing about how the code affects the speed. there are so many layers down there that you can't simply assume anything. benchmark the code to get real facts.
5) don't optimize unless you need to (you probably don't).
so for your question : declare anything with var as much as possible. declaring a variable with var will make them local - when the function ends the reference will get out of scope and the GC can start determine the destruction time for the object earlier. declaring your object without var will make them global - it is unclear when will the GC decide to delete the object, thus slowing things down.
and as you know - declaring variables global can lead to many bugs, keep things scoped. don't use delete. it's just wrong.
Related
I have this code snippet; It basically connects to mongo database and goes through documents. On each iteration it searches for messages array of objects. It creates variable of messages, and then loops through it. Does declared variable (var msg) inside callback function remain in memory or is it destroyed upon end of callback function execution? Would there be any difference if var msg was actually declared as let msg? Is there a way to discard whole scope from the memory?
MongoClient.connect(mongoUrl, (err, db) => {
assert.equal(null,err);
var collection_data = db.collection('threadContents').find();
collection_data.on('data', (doc) => {
var msg = doc.messages;
for (var variable in msg) {
console.log(msg);
}//forin(msg)
});//collection_data.on
});//mongo.connect
In theory - yes.
In practice - it's not that simple...
In your example, var msg does not "leak" outside of it's original scope, so it will most likely get destroyed when callback finishes it's job.
One thing to note - the destruction of this object doesn't have to happen immediately - JS Engines are mostly Garbage Collected, so this piece of memory can stay on the stack for some time, but it won't be reachable anymore.
If you would declare this variable in outer scope, it could possibly stay in the memory if that scope stayed in memory (so, other pieces of code could access that variable). You can read about this behavior in Closures section at MDN.
Another thing to note is usage of console.log. In general, non-primitive values (like Objects or Arrays, which actually are "special" objects), will be accessible by reference, not by value. Therefore, if your var msg is a non-primitive, it will most likely persist in the memory until you clear your console. Primitive values would be copied, so strictly speaking they would still persist in the memory, but probably in another place in the memory (although JIT engines could probably try to optimize that and don't copy the memory if it's not necessary).
Node.js (and all javascript engines) rely on tracing garbage collection, which means that allocated memory is deallocated in a non-deterministic way, i.e. you cannot predict exactly when it will happen. This usually does not affect you, but uif you really want some chunk of memory or some other resource to be deallocated in a predictable way, you have to use some ad-hoc technique.
In your specific example 'msg' will be deleted, but don't expect it to be deleted straight away.
My node/javascript program receives lots of messages.
Each time a message is received I create a new object, passing it message content.
Within the new objects constructor, the object does a bunch of stuff, including some mongo operations with callbacks.
When the operations that are performed within the object constructor are complete, the object is no longer needed or wanted.
After some experiments involving complexity (i.e. storage of the object in an array element or as a property of a 'master' object and then deleting it, I tried the simple approach.
var x = new DisposableObject(message);
delete x;
This seems to work fine. There may be many instances of DisposableObject in existence at any time. DisposableObject is created and does everything expected of it in tests.
I am assuming that when I delete 'x' that this does not affect the object itself, just the reference to it that is contained in 'x'. The objects callbacks occur and all is good.
So four questions:
Will this simple mechanism allow the garbage collector (node/V8) to get rid of the object?
Is there some awful trap door awaiting my code because I am doing this?
Is there any issue with multiple instances of DisposableObject floating around waiting for callbacks when there is no active reference left to them in my program?
Is there a better way to create the objects, then make sure they can be garbage collected after all their operations are completed?
Javascript uses a nongenerational mark-and-sweep garbage collector, in javascript objects are automatically garbage collected when they are no longer needed , so you need not worry about garbage collection.
but you have to keep these points in mind (from this answer):
what you are trying with delete does not really delete an object, delete is only effective on an object's properties. It has no effect on variable or function names., Use delete statements whenever you create an object using a new statement, pair it with a delete statement. This ensures that all of the memory associated with the object, including its property name, is available for garbage collection. The delete statement is discussed more in “Freeing Objects.”
Use the var keyword. Any variable created without the var keyword is created at the global scope and is never eligible for garbage collection, presenting the opportunity for a memory leak.
In case of global variables, Global variables are never disposed of by the GC in the sense that a global variable will always exist. Setting it to null will allow the memory that it references to be collected. the memory used by the object will be eligible for collection. but The variable still exists though, and it simply references null(some more here)
I'm learning Javascript, and in the various texts the authors will speak of javascript using a mark and sweep gc to deallocate objects from memory. They will also speak of how if you set the value a variable references to null it will delete the reference to that value, allowing the allocated space to be set for gc. This SO answer says that you can remove the allocated memory and the reference by setting the value the variable contains to null and then to undefined, effectively removing the allocated space from the heap (if I understood it correctly).
So my question is this: Is it possible to write javascript in such a way that you can eliminate gc?
(If it is implementation specific I would like to know if it is possible on v8, though if this is possible on rhino or other js implementations that would be of immense use too)
Judging by projects like LLJS my request isn't too unreasonable, but I'm not entirely sure how the memory module does it.
I've always found it helpful if I explain why I'm asking so here it goes. I really like compilers, and I wanted to write a compile-to-js language that leveraged a static inferred typing system similar to SML. The reason why I wanted to write my own was because I wanted to utilize region inference to determine exactly when objects and variables come out of scope (as much as possible) and upon leaving scope remove it from the heap, thereby eliminating as much gc as possible. This is mostly a research project (read: because I can) so any resources on memory optimization in javascript would also be greatly appreciated!
EDIT: I guess another way to phrase it would be "Is it possible to write js in such a way that the gc will deterministically never run (as much as possible)? If so what techniques would be involved?"
I'm not looking per se for delete because that marks the element for deletion thereby invoking what I wanted to (try to) avoid, I was curious if the implementation's gc would run if I removed all references (and the value) associated with the variable.
Alternatively, paraphrasing from the referenced SO Answer:
x = foo;
x = null;
x;
Is x still on the heap?
It's not entirely clear what you're looking for.
The standard Javascript implementations have NO way of manually deallocating memory. You can remove a property with the delete operator, but that just removes the property from the object. It doesn't even free any contents that the property points to (that is left for garbage collection if there are no other references to that data).
Javascript was designed from the ground up to be a garbage collected language. It frees things from physical memory only when the garbage collector runs and that garbage collector finds objects that are unreachable (e.g. there are no references to those objects still in use). The language does not contain commands to free memory.
It is possible (in some JS implementations) to call the GC yourself rather than wait for the JS engine to run it, but it's still using GC to decide what to free.
Responding to the additional things you added to your answer.
To the best I know, javascript only cleans things up when the GC runs. Until then objects are marked such that the GC can see that there are no references to them anywhere, but they aren't actually freed until the GC checks and notices this. Further, local variables in a function scope are themselves a type of object and those are not freed until the GC runs and notices that there are no references to the function scope (in JS, a closure can maintain a reference to a function scope even after the function has completed).
So, in your code example:
x = foo; x = null; x;
x is still alive and occupying some space because it's still in scope and code could still reach it. It's contents will be null which presumably takes no extra space beyond the variable itself, but the space for the variable itself won't be freed until the function context it is in is found to be reference free by the garbage collector.
JS is a garbage collected language. That's when things are actually freed from the heap. There are no instructions in the language to free things anytime sooner.
The delete keyword will trigger garbage collection by the browser. Be aware that it deletes entire chains of objects unless you nullify object references.
var o = {...};
delete o;
I want to know what is the best way of accessing a JavaScript object, dot operator or []:
data.property or data["property"]?
Both are more or less the same, except in Safari in which case dot notation is significantly faster.
You're much better off concentrating on DOM manipulation, DOM size, and CSS complexity as major sources of performance problems in Javascript applications.
That said, if you are doing a lot of property access in a loop, a local variable will be much faster than either property access or array lookup. Copy an object property into a variable if it is going to be accessed repeatedly. Do not use the "with" statement, incidentally. It can slow down local variable access by introducing another object into the scope chain.
Variables defined in local scope will be accessed far more quickly than those in global, as the Javascript engine first looks through all of the variables locally, then checks all of the variables in global scope. Scopes can nest as well, so the farther up the nesting chain the variable resides the longer it will take to find. That's why it's best to cache something like "document" in a local variable if it is going to be accessed more than once.
Both are the same speed. Also, if you are concerned with the level of speed in accessing a field attached to a reference, I think you might be going down the wrong path to tuning your code.
I would venture to guess that data.property is ever-so-slightly faster, but it may be difficult to measure. Indeed, JSPerf shows no distinction
The best way of accessing object properties has generally nothing to do with speed. Dot operator is used for syntactic sugar (I.E. this.hasElements() is easier to read, write and process in your brain than this["hasElements"]()) whenever possible and the brackets are used when the key name is a variable or has illegal characters.
I am making a webapp. I have a fairly basic question about javascript performance. Sometimes I need a global variable to store information that is used the entire time the website is open.
An example is a variable called needs_saved. It is true or false to say whether the page needs saved. I might have another variable called is_ie, ie_version, or space_remaining.
These are all variable that I need in various functions throughout the app.
Now, I know global variables are bad because they require the browser to search each level of function scope. But, I don't know if there is any better way to store values that are needed throughout the program.
I know I could create a global object called 'program_status' and give it the properties is_ie, ie_version, etc... But is this any better since it would first have to find my program_status object (stored as a global variable), and then the internal property?
Maybe I'm overthinking this.
Thanks
You have nothing to worry about.
The performance impact of a global variable is minute.
Global variables are discouraged because they can make code harder to maintain.
In your case, they won't.
The reason global variable use should be kept to a minimum is because the global namespace gets polluted when there's a lot of them, and there's a good chance of a clash if your program needs to use some 3rd party libraries which also create their own globals.
Creating a single object to hold all of your global state is a good idea since it limits the number of identifiers you need to reserve at the global level.
To solve performance problems, you can then create a local reference to that object in any scope where you need to access it multiple times:
So instead of
if (globalState.isIe) { alert(globalState.ieMessage); }
you can do
var state = globalState;
if (state.isIe) { alert(state.ieMessage); }
You don't need to do this if you only access the state object once. In any case, even if you never do this, the performance penalties will be negligible.
If you're worried about performance, code something clean then run a profiler on it to optimize. I know both Safari and Google Chrome have one, and it's pretty sure Firebugs includes one for Firefox too. Heck, even Internet Explorer 8 has one.