Are NewGlobalRef / DeleteGlobalRef calls "recursive"? - android-ndk

A very basic question, but I don't see it explained anywhere in the docs. Say I have a jobject (or jclass). I create a global ref (NewGlobalRef) and store it for later use. Then I create another one and store it again. Then I delete the second ref, then I delete the first one. Will it work as I expected - ensuring the object is kept alive and all non-deleted references valid as long as the number of NewGlobalRef calls is greater than the number of DeleteGlobalRef calls for this object?

Yes.
Each JNI global and local reference is an individual garbage collection root. Roots refer to the first objects considered alive during a mark and sweep. An single object could have any number JNI references to it.
Of course, objects can reference other objects, so just because you delete all JNI references to an object doesn't mean it's no longer alive.
As for "recursive", I thought you meant something else. JNI references just reference heap objects and are not heap objects themselves. So, there is no recursion involved.
Some further reading at IBM's Overview of JNI object references.

Related

UE4: How can i detect if an actor refrence has been destroyed in blueprints?

In a level, I'm spwaning an actor which is designed to exist at some times and not at others. I'm spawning the actor fine, and plan to destroy it when i don't need it. But I want to make sure I'm not going to be in a state where I'm trying to act on the actor when it doesn't exist.
I'm thinking along the lines of a c++ object pointer with new, delete and nullptr. I initailise the variable to nullptr, assign the pointer when i use new, delete the pointer when i'm done, then re-assign the variable as nullptr. This is so i can check if the pointer is valid or not by checking that it's not equal to nullptr.
What (if anything) is the equivalent of this seemly basic concept in UE4's blueprints?
You can check if an object reference variable is non-null and not pending destruction using the Is Valid node:
If you only need branching behavior, you can right click on the Get node for that object reference and select Convert to Validated Get:
(credit to #Thunder_Owl on twitter for images)
So, basically you can have a reference (maybe in your level or GameMode) to the most recent instance of that spawned actor, and then where you want to check if it's destroyed, you can check if that reference is currently valid.

How does Java garbage collector deals with circular references when their access path is broken?

I just want someone explain it to me that how does GC discover that those memory blocks (pictured in red area) are garbage when their reference count is more that 0 but they are practically inaccessible?
There's set of "root objects" which are considered always accessible: e.g., Thread references, static variables, class references. If some object can not be reached via link of references from these root objects, it considered to be available for GC, even if there are some references to that object.
GarbageCollector works based on Java Memory Model. In java available application memory is divided in two parts: Heap and Stack. A object is stored in heap memory and can be accessed by 2 ways :-
1) Object can have reference variable which is stored in stack memory. In this case object can be directly accessed by using it's reference variable.
2) Object can be contained by any other object and would not have any reference in stack memory. In this case this object can be accessed only by using that container object. So if container object is garbage collected then this object must be eligible for garbage collection.
While doing GarbageCollection GarbageCollector checks whether a object is accessible directly or indirectly by any reference available in stack if it is then it won't collect this object else it do collect it.
The details of the GC algorithm are implementation dependent in Java, so it depends on your VM. But most VMs do not use reference counting. The official VM even has several configurable algorithms available. So it is hard to generalize about this.

query regarding Garbage collector

i know GC release the memory of obj which is not used in any further but i know one thing that GC release memory in which form of like object or refrence or value....
please help me.
thanks in advance...
As a response to the comments to the question, it seems that you need clarification of a few concepts:
In .NET, objects live somewhere in the memory. A reference is kind of like a pointer to such an object/memory location. A value is some integral value (a number like 123).
For example, say you have an object of type MyClass, and you have created a new instance. This object contains a string. That string is another object, and your instance of MyClass holds a reference to the string object.
The garbage collector operates only on objects. It keeps track of the references to an object, if nobody is referencing the object any more the garbage collector can free that object up. In our example, if the garbage collector notices there's nobody holding a reference to the instance of MyClass, then it makes sure that object is freed. That in turn makes the reference to the string disappear, and the garbage collector can then also free the string (if nobody else is holding a reference, of course). Values don't need to be treated in any special way as they are part of the memory that belongs to an object (and thus cannot be freed "independently").
The same is true with Java, BTW.
An object of a reference type (a class) becomes garbage when no references to it exist anymore. It will be collected some time after that, whenever the GC runs next. The reason why these objects can be garbage is because they can be referenced from multiple places in the program, so no individual part of the program can release the object because other parts might still need it. The GC's responsibility is to discover when no part of the program needs the object anymore.
An object of a value type (a struct, or a built-in type like an integer) is simply copied to each place that needs to use it, so there's no problem of one value being used from multiple parts of the program. No GC is needed for value types, because they're always part of something else that ensures they're released. A value stored on the stack (e.g. a local variable within a method) is released when the method returns. A value stored in a class object is released when that class object becomes garbage.

Can I use [self retain] to hold the object itself in objective-c?

I'm using [self retain] to hold an object itself, and [self release] to free it elsewhere. This is very convenient sometimes. But this is actually a reference-loop, or dead-lock, which most garbage-collection systems target to solve. I wonder if objective-c's autorelease pool may find the loops and give me surprises by release the object before reaching [self release]. Is my way encouraged or not? How can I ensure that the garbage-collection, if there, won't be too smart?
This way of working is very discouraged. It looks like you need some pointers on memory management.
Theoretically, an object should live as long as it is useful. Useful objects can easily be spotted: they are directly referenced somewhere on a thread stack, or, if you made a graph of all your objects, reachable through some path linked to an object referenced somewhere on a thread stack. Objects that live "by themselves", without being referenced, cannot be useful, since no thread can reach to them to make them perform something.
This is how a garbage collector works: it traverses your object graph and collects every unreferenced object. Mind you, Objective-C is not always garbage-collected, so some rules had to be established. These are the memory management guidelines for Cocoa.
In short, it is based over the concept of 'ownership'. When you look at the reference count of an object, you immediately know how many other objects depend on it. If an object has a reference count of 3, it means that three other objects need it to work properly (and thus own it). Every time you keep a reference to an object (except in rare conditions), you should call its retain method. And before you drop the reference, you should call its release method.
There are some other importants rule regarding the creation of objects. When you call alloc, copy or mutableCopy, the object you get already has a refcount of 1. In this case, it means the calling code is responsible for releasing the object once it's not required. This can be problematic when you return references to objects: once you return it, in theory, you don't need it anymore, but if you call release on it, it'll be destroyed right away! This is where NSAutoreleasePool objects come in. By calling autorelease on an object, you give up ownership on it (as if you called release), except that the reference is not immediately revoked: instead, it is transferred to the NSAutoreleasePool, that will release it once it receives the release message itself. (Whenever some of your code is called back by the Cocoa framework, you can be assured that an autorelease pool already exists.)
It also means that you do not own objects if you did not call alloc, copy or mutableCopy on them; in other words, if you obtain a reference to such an object otherwise, you don't need to call release on it. If you need to keep around such an object, as usual, call retain on it, and then release when you're done.
Now, if we try to apply this logic to your use case, it stands out as odd. An object cannot logically own itself, as it would mean that it can exist, standalone in memory, without being referenced by a thread. Obviously, if you have the occasion to call release on yourself, it means that one of your methods is being executed; therefore, there's gotta be a reference around for you, so you shouldn't need to retain yourself in the first place. I can't really say with the few details you've given, but you probably need to look into NSAutoreleasePool objects.
If you're using the retain/release memory model, it shouldn't be a problem. Nothing will go looking for your [self retain] and subvert it. That may not be the case, however, if you ever switch over to using garbage collection, where -retain and -release are no-ops.
Here's another thread on SO on the same topic.
I'd reiterate the answer that includes the phrase "overwhelming sense of ickyness." It's not illegal, but it feels like a poor plan unless there's a pretty strong reason. If nothing else, it seems sneaky, and that's never good in code. Do heed the warning in that thread to use -autorelease instead of -release.

How does the Garbage Collector decide when to kill objects held by WeakReferences?

I have an object, which I believe is held only by a WeakReference. I've traced its reference holders using SOS and SOSEX, and both confirm that this is the case (I'm not an SOS expert, so I could be wrong on this point).
The standard explanation of WeakReferences is that the GC ignores them when doing its sweeps. Nonetheless, my object survives an invocation to GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced).
Is it possible for an object that is only referenced with a WeakReference to survive that collection? Is there an even more thorough collection that I can force? Or, should I re-visit my belief that the only references to the object are weak?
Update and Conclusion
The root cause was that there was a reference on the stack that was locking the object. It is unclear why neither SOS nor SOSEX was showing that reference. User error is always a possibility.
In the course of diagnosing the root cause, I did do several experiments that demonstrated that WeakReferences to 2nd generation objects can stick around a surprisingly long time. However, a WRd 2nd gen object will not survive GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced).
As per wikipedia "An object referenced only by weak references is considered unreachable (or "weakly reachable") and so may be collected at any time. Weak references are used to avoid keeping memory referenced by unneeded objects"
I am not sure if your case is about weak references...
Try calling GC.WaitForPendingFinalizers() right after GC.Collect().
Another possible option: don't ever use a WeakReference for any purpose. In the wild, I've only ever seen them used as a mechanism for lowering an application's memory footprint (i.e. a form of caching). As the mighty MSDN says:
Avoid using weak references as an
automatic solution to memory
management problems. Instead, develop
an effective caching policy for
handling your application's objects.
I recommend you to check for the "other" references to the weakly referenced objects. Because, if there is another reference still alive, the objects won't be GCed.
Weakly referenced objects do get removed by garbage collection.
I've had the pleasure of debugging event systems where events were not getting fired... It turned out to be because the subscriber was only weakly referenced and so after some eventual random delay the GC would eventually collect it. At which point the UI stopped updating. :)
Yes it is possible. If the WeakReference is located in another generation than the one being collected, for example, if it is in the 2nd Generation, and the GC only does a Gen 0 collection; it will survive. It should not survive a full 2nd Gen collection that completes and where all finalizers run, however.

Resources