Having a problem with objects, not needed any more but still having references.
Result: size of allocated memory is constantly growing due to not collected objects.
How to solve this sort of problem?
Is there any way to find objects with only one reference, or objects with lifetime more than some value? Or any another solution?
Using Lua 5.1 and C++ with luabind.
Thanks.
As someone is mentioning here, you can try using weak tables.
If you have some code like this:
myListOfObjects = {}
...
table.insert(myListOfObject, anObject)
Then once anObject stops being used, it will never be deallocated since myListOfObjects still references it.
You could try removing the reference in myListOfObjects (setting the reference to nil) but a simpler solution is declaring myListOfObjects as a weak table:
myListOfObjects = {}
setmetatable(myListOfObjects, { __mode = 'v' }) --myListOfObjects is now weak
Given that setmetatable returns a reference to the table it modifies, you can use this shorter idiom, which does the same as previous two lines:
myListOfObjects = setmetatable({}, {__mode = 'v' }) --creation of a weak table
I'm not certain about integrating it with C++ but it sounds like the garbage collector isn't being given an opportunity to run.
In your lua you could try explicitly invoking it and see if that helps. There is a function in the core apis collectgarbage(opt [, arg]).
Related
I am familiar with things like
if ( isDefined( 'URL' ) ) structAppend( request.context, URL );
if ( isDefined( 'Form' ) ) structAppend( request.context, Form );
Which is how FW/1 builds rc. I recently got handed some code that does this
_inputs = duplicate(url);
structAppend(_inputs, form);
What is duplicate() doing here? How is that different from structAppend()?
I wonder if the original developer had come across issues when using the StructCopy() method and carried that over into their code for the StructAppend() method? I know that the StructCopy() method will copy nested structures by reference which can bite you. That is an example of when I use the Duplicate() method (to make a completely new copy of a structure).
I don't think that StructAppend() works that way though. Perhaps they wrote that code in an overabundance of caution. Obviously, this is just a guess.
The StructCopy() method is documented to copy by reference.
Copies a structure. Copies top-level keys, values, and arrays in the structure by value; copies nested structures by reference.
Where as the StructAppend() method makes no mention of it.
I am implementing my own Map in Java, using a custom class I made.
I already implemented the hashCode and equals without any problem.
I just have a question more related into performance and stuff like that.
So I will check many times in my application if a specific value is inside the map, for that, for that I have to create a object and then use the methods containsKey of Map.
My question is...
Is there any other way? without being always creating the object???
I cant have all the objects in my context universe, so that isn't a way...
I know I can just point the object to 'null' after using it, but still, it's not so elegant, creating objects just to check if there is the same object inside =S
Are there any other conventions?
Thank you very much in advance!
EDIT:
Stuff typed = new Stuff(stuff1, stuff2, (char) stuff3);
if(StuffWarehouse.containsKey(typed))
{
//do stuff
}
//after this I won't want to use that object again so...
typed = null;
The code below is showing a poor example of memory management; item is never de-allocated because a temporary copy of it is returned instead.
I've been scouring programming forums on and off for weeks but haven't found a clear explanation as to how to properly return a valid instance of type Item* while allowing item to be de-allocated.
In other words, what is a better alternative to this code that accomplishes the same return value and yet allows item to be de-allocated?
Item* Inventory::add(const string& name)
{
Item* item = new Item(name);
...(some other code here)...
return item;
}
Thanks!
You might think everything is destroyed once it goes outside the loop, but the pointer that is returned (and the memory that it points to) will stay. It is transferred to the object that calls this method, and no memory is leaked.
I'm having a look at the code at this page:
http://golang.org/pkg/net/http/
And there's one thing I don't understand - at some point, a new structure is created and initialized like this:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
Why use & when creating this structure?
I've also read this blog post and structs are initialized like this:
r := Rectangle{}
What is the difference between both and how should I know which one to use?
The difference is in the type of your variable.
client := &http.Client{
makes client of type *http.Client
while
client := http.Client{
builds a http.Client.
The top one is returning a pointer. It is a Go idiom instead of using new. The second one is just a value object. If you need a pointer use the top.
Check the effective go doc for more about this
http://golang.org/doc/effective_go.html#allocation_new
In object-oriented programming, in order for an object to have dynamic lifetime (i.e. not tied to the current function call), it needs to be dynamically allocated in a place other than the current stack frame, thus you manipulate the object through a pointer. This is such a common pattern that in many object-oriented languages, including Java, Python, Ruby, Objective-C, Smalltalk, JavaScript, and others, you can only deal with pointers to objects, never with an "object as a value" itself. (Some languages though, like C++, do allow you to have "objects as values"; it comes with the RAII idiom which adds some complexity.)
Go is not an object-oriented language, but its ability to define custom types and define methods that operates on that custom type, can be made to work very much like classes and methods. Returning a pointer to the type from the "constructor" function allows the "object" to have a dynamic lifetime.
When we use reference, we use a single item throughout the program runtime. Even if we assign that to a new variable or pass through a function. But when we use value, we make new copies of individual items.
( Reference is not right word according to golang convention. "Address of value" would be more appropriate here https://golang.org/ref/spec#Package_initialization )
An example will make it much clear I hope.
type Employee struct {
ID int
Name string
Address string
}
func main() {
andy := &Employee{}
andy.Name = "Andy"
brad := andy
brad.Name = "Brad"
fmt.Println(andy.Name)
}
The result of this code block would be:
Brad
As we made new variable from it but still referring to same data. But if we use value instead of reference and keep the rest of the code same.
// from
andy := &Employee{}
// to
andy := Employee{}
This time the result would be:
Andy
As this time they both are individual items and not referring to same data anymore.
I've been a little surprised, because I have read before, that __gc metamethod is only called for userdata and never for tables. (LuaFAQ : Why don't the __gc and __len metamethods work on tables?)
But, recently, I have tried it and found it actually works! Try this code with Lua 5.2.1:
do
local b = setmetatable({a = 1}, {__gc = function(self) print(self.a); end});
end
collectgarbage();
But I can't find anywhere the changelog for this, so I'm little frustrated and afraid to use it.
Maybe, someone can prove my suggestion? Or it is an undocumented behaviour?
As for me it will be nice to have a regular way to create table destructor, and I will be glad if my observation is right.
The Lua 5.2 Reference Manual section 2.5.1 indicates that tables do support the __gc metamethod. Specifically, it says
For an object (table or userdata) to be finalized when collected, you must mark it for finalization. You mark an object for finalization when you set its metatable and the metatable has a field indexed by the string "__gc".
The similar documentation in the 5.1 Reference Manual says
Using the C API, you can set garbage-collector metamethods for userdata
It seems pretty clear that Lua 5.2 now explicitly supports the __gc metamethod for tables.