Are counters garbage collected? - garbage-collection

In the counters documentation I don't see any option to free a counter array. Can I assume they will be garbage collected or cleaned in some other way without my action?

According to the documentation they will be garbage collected as soon as no more process will reference them:
Counters are not tied to the current process and are automatically garbage collected when they are no longer referenced.

Related

Is it possible to skip an object from collecting by v8 GC?

I have a lot of a long live objects in memory(~10GB) and I definitely know that these objects never be collected by GC. The problem is that a mark-sweep gc action take a long time(90sec) to check all objects in memory and its relations. I need some way to skip my objects from collecting.
I've tried to use Persistent::MarkIndependent, but it doesn't work for me.
If the objects in question are references held live via handles from C++ than they will not be collected. However, the collector still has to traverse them, because it has to find all references to other objects that they contain. If it didn't do that then you would potentially get dangling pointers and make the VM crash.
So, no, at least the way you describe it, that can't be done. (If, on the other hand, these objects cannot contain random pointers because e.g. they are array buffers or strings then the GC knows that it doesn't need to traverse them so there shouldn't be a performance issue.)

How can I monitor the haxe cpp garbage collector?

I would like to ensure the garbage collector is not overused in haxe (cpp target).
I already have pools of large objects and frequently reused objects that I managed to efficiently recycle. But there are still some slowdowns. I'm sure I can limit some of the inconsistent slowdowns and skipped frames by reducing garbage collection.
How can I collect data about the gc? I would like to see the list of classes collected, the number of times they are collected and the number of objects registered in the GC.
Is there an option for that?
untyped __cpp__('code'); will let you execute arbitrary cpp code(passed as it is). Using this construction you can access any inner mechanisms, including garbage collector, so if youlook in gc implementatio, you can do anything you want I guess. You also can directly patch gc part of haxe after it was compiled to cpp.
For Haxe 3.1, use cpp.vm.ExecutionTrace.traceFunctions(); , traceLines, traceOff

Reference counting without Garbage Collection

I am taking a course on programming language design, and one of the topics is Garbage Collection. I understood from the material that RC can be used for GC, but that it also has other uses, and that some languages implement RC but not GC.
What exactly is the use of RC if not for GC?
(RC - reference counting. GC - garbage collection)
Reference counting may be used, eg, to close unreferenced file handles, or to somehow "archive" currently unreferenced data (that can potentially be rereferenced through some indirect path in the future).
I can provide a specific example of reference counting used independently of garbage collection. Objective-C uses reference counting to manage the lifetime of its objects, without the presence of a garbage collector in most cases.
This is done through balanced calls to -retain and -release when dealing with objects. Basically, an object is created with a retain count of 1, and every object that needs to hold on to a reference to an object should increase its retain count by 1 when being passed it initially, then decrement the retain count by 1 when done with it. The final -release call that causes the object's retain count to drop to 0 (no one should have a need for it anymore) triggers the internal mechanisms of the object type to deallocate itself.
No garbage collector process is required for this to take place. In fact, there wasn't a garbage collector for this on Apple's platforms (who are by far the largest users of Objective-C) until fairly recently, and that's not even used for its iOS mobile devices (and is now deprecated on the Mac desktop).
The reference counting in Objective-C is by default manual in nature, requiring developers to follow certain conventions to make sure that you safely balance retain and release calls to avoid leaks or premature deallocations. A newer system was just implemented within the LLVM compiler that automates this, and adds the appropriate calls at compile-time. This automatic reference counting removes much of the effort of managing memory while removing the need for a garbage collector process to sweep object graphs.
One specific condition that a garbage collector can handle that reference counting cannot is the detection and removal of retain cycles. Objects that hold strong references to that point back upon themselves in a cycle will never be deallocated under standard reference counting, even if all objects referencing those in the cycle release the references to those within it. A garbage collector will see that this cycle is not rooted in the larger object graph and will be able to remove the entire cycle when it performs a sweep.

How do garbage collectors track all live objects?

Garbage collection involves walking through a list of allocated objects (either all objects or objects in a particular generation) and determining which are reachable.
How is this list maintained? Do runtimes for GC languages keep a giant list of all objects?
Also, from what I understand, GC involves walking the call stack to look for object references - how does the algorithm distinguish between GC-able pointers and primitive data?
The memory management system keeps track of the size of each allocated object, just like it does in C or C++. One way this is commonly done is for the memory management system to allocate an extra size_t before each allocation, that keeps track of the size of each objecct. The memory manager likewise has to keep track of the size of each free block, so that it can reuse blocks to allocate them.
The garbage collector works in two phases: the mark phase, and the sweep phase. In the mark phase, the garbage collector starts walks object references in order to find objects that are still reachable. The garbage collector starts at a few basic places where the object references are stored and given names (the stack, and global storage, and static storage), and then traverses references in the objects.
In the sweep phase, the garbage collector walks the heap from bottom to top, jumping from allocation to allocation based on those size_ts, and frees anything that isn't marked.
Some languages (like Ruby) tag all of the primitives so that they can be identified separately from the object references at runtime. Other garbage collectors are ver conservative and follow primatives as through they were object references (though some checks must be performed to make sure that the garbage collector doesn't stick a mark in the middle of some other object). Still other languages use runtime type information to be more precise about whether they follow primatives.
Ruby's garbage collector sometimes called "conservative" because it doesn't check whether the space on the stack is actually being used, so it sometimes keeps dead objects alive by following ghost references on the stack. But since it always knows exactly whether the data it's looking at is a reference or a primative, I don't call it conservative here.
Garbage collection involves walking through a list of allocated objects (either all objects or objects in a particular generation) and determining which are reachable.
Not really. GCs are categorized into tracing and reference counting (see A unified theory of garbage collection). Tracing GCs start from a set of global roots and trace all objects reachable from them. Reference counting GCs count the number of references to each object and reclaim it when the count reaches zero. Neither require a list including unreachable objects.
How is this list maintained? Do runtimes for GC languages keep a giant list of all objects?
Pedagogical solutions like the one in HLVM can keep a list of all objects because it is simple but this is rare.
Also, from what I understand, GC involves walking the call stack to look for object references - how does the algorithm distinguish between GC-able pointers and primitive data?
Again, there are many different strategies. Conservative GCs are unable to distinguish between pointers and non-pointers so they conservatively consider that non-pointers might be pointers. Pedagogical GCs like the one in HLVM can use algorithms like Henderson's Accurate GC in an uncooperative environment. Production GCs store enough information in the OS thread stack to determine exactly which words are pointers (and which stack frames to skip because they are not affiliated with managed code) and then use a stack walker to find them.
Note that you also have to find local references held in registers as well as on the stack.
This site ( How Java’s Garbage Collector Works? ) has a good, brief explanation on how garbage collectors work, not just the default Java one.

Why does Lua use a garbage collector instead of reference counting?

I've heard and experienced it myself: Lua's garbage collector can cause serious FPS drops in games as their scripted part grows.
This is as I found out related to the garbage collector, where for example every Vector() userdata object created temporarily lies around until getting garbage collected.
I know that Python uses reference counting, and that is why it doesn't need any huge, performance eating steps like Luas GC has to do.
Why doesn't Lua use reference counting to get rid of garbage?
Because reference counting garbage collectors can easily leak objects.
Trivial example: a doubly-linked list. Each node has a pointer to the next node - and is itself pointed to by the next one. If you just un-reference the list itself and expect it to be collected, you just leaked the entire list - none of the nodes have a reference count of zero, and hence they'll all keep each other alive. With a reference counting garbage collector, any time you have a cyclic object, you basically need to treat that as an unmanaged object and explicitly dispose of it yourself when you're finished.
Note that Python uses a proper garbage collector in addition to reference counting.
While others have explained why you need a garbage collector, keep in mind that you can configure the garbage collection cycles in Lua to either be smaller, less frequent, or on demand. If you have a lot of memory allocated and are busy drawing frames, then make the thresholds very large to avoid a collection cycle until there is a break in the game.
Lua 5.1 Manual on garbage collection
Reference Counting alone is not enough for a garbage collector to work correctly because it does not detect cycles. Even Python does not use reference counting alone.
Imagine that objects A and B each hold a reference to each other. Even once you, the programmer no longer hold a reference to either object, reference counting will still say that objects A and B have references pointing to them.
There are many different garbage collecting schemes out there and some will work better in some circumstances and some will work better in other circumstances. It is up to the language designers to try and choose a garbage collector that they think will work best for their language.
What version of Lua is being used in the games you are basing this claim on? When World of Warcraft switched from Lua 5.0 to 5.1, all the performance issues caused by garbage collection were severely diminished.
With Lua 5.0's garbage collection, the amount of time spent collecting garbage (and blocking anything else from happening at the same time) was proportional to the amount of memory currently in use, leading to lots of effort to minimize the memory usage of WoW addons.
With Lua 5.1's garbage collection, the collector changed to being incremental so it doesn't lock up the game while collecting garbage like it previously did. Now garbage collection has a very minimal impact on performance compared to the larger issue of horribly inefficient code in the majority of user created addons.
In general, reference counting isn't an exact substitute for garbage collection because of the potential of circular references. You might want to read this page on why garbage collection is preferred to reference counting.
You might also be interested in the Lua Gem about optimization which also has a part that handles garbage collection.
Take a look at some of the CPython sources. A good portion of the C code is Py_DECREF and Py_INCREF. That nasty, tedious and error-prone book keeping just goes away in Lua.
If required, there's nothing to stop you writing Lua modules in C that manage any heavy, private allocations manually.
It's a tradeoff. People have explained some reasons some languages (this really has nothing to do with Lua) use collectors, but haven't touched on the drawbacks.
Some languages, notably ObjC, use reference counting exclusively. The huge advantage of this is that deallocation is deterministic--as soon as you let go of the last reference, it's guaranteed that the object will be freed immediately. This is critical when you have memory constraints. With Lua's allocator, if memory constraints require predictable deallocation, you have to add methods to force the underlying storage to be freed immediately, which defeats the point of having garbage collection.
"WuHoUnited" is wrong in saying you can't do this--it works extremely well with ObjC on iOS, and with shared_ptr in C++. You just have to understand the environment you're in, to avoid cycles or break them when necessary.

Resources