What happens to multiple references to the same object in JNI? - java-native-interface

I'm using JNI to access some Java code from C++. Object references returned by the JNI must be cleaned up, but what happens if multiple methods return the same Java object? Do I need to call Delete on each of them?
E.g. java.nio.Buffer has a method clear() that clears the buffer and returns itself.
If I first create a buffer with JNI, then call clear(), do I need to clean up both jobjects, or am I good to only clean up one of them?

In JNI you have Java objects and Java object references. A jobject is an object reference that points to a Java object and that you can release with DeleteLocalRef if you don't need it anymore.
Calling clear() on a Buffer object will create a new reference for the returned object, even if it actually points to the same object. So yes, if you run out of local references, you should release all references to your Buffer but the one, you're working with.

Related

What is the best practice of passing reference counted C++ objects to Lua?

I want to have my reference counted C++ object also managed in Lua callbacks: when it is held by a Lua variable, increase its refcount; and when the Lua variable is destroyed, release one refcount. It seems the releasing side can be automatically performed by __gc meta-method, but how to implement the increasing side?
Is it proper&enough to just increase refcount every time before adding the object to Lua stack?
Or maybe I should new a smart pointer object, use it everywhere in Lua C function, then delete it in __gc meta-method? This seems ugly as if something wrong with the Lua execution and the __gc is not called, the newed smart pointer object will be leaked, and the refcounted object it is referring would have leak one count.
In Perl that I'm more familiar with, this can be achieved by increase refcount at OUTPUT section of XS Map, and decrease refcount at destroyer.
I assume you have implemented two Lua functions in C: inc_ref_count(obj) and dec_ref_count(obj)
local MT = {__gc = dec_ref_count}
local setmetatable = setmetatable
local T = setmetatable({}, {__mode="k"})
function register_object(obj)
if not T[obj] then
T[obj] = setmetatable({}, MT)
inc_ref_count(obj)
end
end
Invoke register_object(object) on C side every time you send a ref-counted C object to Lua
You may leak memory if Lua VM crashed or was closed.
After more study on Lua manual, I found that light user data does not support metatable (see document). It should be implemented via heavy user data (lua_newuserdatauv) that allocates a chunk of memory by Lua machine. I can placement new a smart pointer object using this memory chunk, and bind a __gc on it.

Managing pointers to destroyed objects in a game engine in an elegant way

I'm currently building a game engine, and have run into a bit of a problem. I have found a couple of solution, but it's quite as elegant as I would like them to be.
Here's the issue:
Instantiate Object A in the engine
Get a pointer to Object A - ObjectA*
Destroy Object A
ObjectA* becomes a dangling pointer
Using shared_ptr is a no-go since it can lock objects, which we don't want. There's nothing wrong with Object A being destroyed, I just need a way to check whether it has.
I have two solutions for this issue:
The first is simply to return a surrogate object whenever you want a reference to an object. This surrogate object could have an implicit conversion to a raw pointer, for cases where we know for certain the object is valid. In cases where we keep the reference around for longer, we would use the surrogate object, which is basically just a pointer to a pointer. When the object is destroyed we simply set its pointer to nullptr, which the surrogate would then be able to check for
The second solution is to not return pointers at all. Instead, whenever we want a reference to an object, we pass along the pointer we want it assigned to as a parameter. The engine will then keep said pointer in memory and manually set it to nullptr when the object is destroyed.
Here are the requirements for my preferred elegant solution:
Only uses raw pointers for references
Said raw pointers are returned from function calls (i.e. Ptr* AddCompoenent<>() instead of void AddComponent<>(Ptr*&)
Pointers will become nullptr when the object they point to is destroyed
Is this at all possible?
If you want to return simple pointers, there is no way of collecting all pointers to the object when you deallocate it and setting them to nullptr if you just use normal C++ objects.
There is of course a solution, it's not new, and it's called garbage collection. This is exactly the algorithm you'd need to do it; it analyzes the stack and heap and is able to collect all pointers to your object. Just instead of keeping the object if it finds pointers to it, you want it to set the pointers to nullptr.
Now there are a couple of prerequisites to garbage collection. One is that you must be able to recognize all pointer values on the stack and heap at runtime, so that you can be sure that some data is actually a pointer to your object and not just some integer or other value that happens to hold a value that looks like a pointer to your object. If you still want to have simple pointer types in your code, you need support from your compiler to have that information at runtime – and C++ does not provide it. This is why garbage collection is typically defined for a whole language.
Moreover, the performance implications of using this algorithm are horrendous: Every time you deallocate an object, you would need to analyze all stack and heap. This would mean it runs far more often than a normal gc-based language runs it, and look at their performance losses due to it.

Lua userdata lifetime management

Im pushing a c++ object pointer to userdata from few different places in my c++ code. I would like lua to manage the lifetime of the c++ object (userdata). My problem is that now I have multiple instances of userdata pointing to the same c++ object in the lua environment. So GC will be called when each instance.
I was thinking that one solution would be to create some weak cache table in the lua registry (LUA_REGISTRYINDEX) to map object pointer to the actual userdata. Then when I push userdata to the environment I check this cache to see if the userdata has already been created and push that instance (otherwise create userdata and add to the cache). That way only one instance of the userdata exists in the environment.
Is this the best solution or am I missing something?
The correct answer is to stop doing this:
I have multiple instances of userdata pointing to the same c++ object in the lua environment
When you give an object to Lua, then Lua owns that object. If a pointer to that object finds its way back into C++, then those C++ APIs should not be able to grant ownership of that object to anywhere else. Including back to Lua again. So there shouldn't be a bunch of functions that can return points to the same object to Lua.
And if you do have a bunch of such functions, you need to re-evaluate whether Lua should have ownership of these objects, or whether it should just be able to use them. You'd be surprised how rarely you genuinely need to give ownership of objects to Lua.
If you absolutely cannot avoid transferring ownership, then this means that your ownership semantics are not strict. That is, there isn't a single system which owns an object. You share ownership of an object with several places.
In C++, that's spelled shared_ptr. Therefore, your userdata should store a shared_ptr<T> to the object being managed. The GC should destroy the shared_ptr, which will only destroy the managed T if all other instances of shared_ptrs which share ownership with it have been destroyed.

Proper way to manage Lua light userdata

I have a void * to a C++ created object that I pass to Lua using lua_pushlightuserdata(). Lua can perform some actions on that light userdata by passing it to Lua CFunctions and retrieving it with lua_touserdata(). At some point in the future the C++ object is destructed by its owner (C++), memory freed, and set to null. However, Lua still has a reference to this pointer, it doesn't know that it has been destroyed.
Now my Lua functions that take in this userdata make sure the pointer is valid. But what is the best approach for informing Lua that their reference to the light userdata is no longer valid? Do I expose an IsValid(lightuserdata) function to Lua so it can query the status? Or is there a better approach that I am missing.
In my experience I found that it's easier to make Lua own the objects, and you need full userdata to hold the pointer or complete object within userdata memory area. Full userdata can have metatable with __gc metamethod, so objects would be destroyed only after the last reference is garbage-collected on Lua side.
At least don't expose raw pointers to native objects to Lua through lightuserdata, it doesn't really work for native objects lifetime management. Make it some object that is owned by Lua. In simplest case it could be a Lua object (full userdata) holding smart pointer to real native object.

Reference counting in wxWidgets, how does it work in this simple case?

My program is crashing and I'm having a hard time wrapping my head around why it crashes. The main problem is that the wxwidgets documentation says that reference counting is used for wxImage objects. What exactly does this mean? Why does this code crash it?
wxImage* t = m_default_image; //m_default_image is a pointer pointing to a valid wxImage object.
wxDELETE(m_default_image);
if(t->IsOk())
{
wxLogMessage("reference counting works!");
}
The line that crashes is the t->IsOK(). Shouldn't the reference counting prevent the actual object from being deleted so my t ptr still points to something valid?
Let me explain what is happening:
You create a pointer to a wxImage that you have already created somewhere.
You then delete it.
You then attempt to dereference a deleted pointer and call 'IsOk()' on the resulting object, which doesn't exist anymore, because of the previous step.
Step 2 may or may not have actually deleted the object, but it likely deleted the reference as well. Depending on how wx implemented reference counting, and how you've managed references, the wxImage object may have a reference count of one at the start of your routine - therefore, wxDELETE will reduce the reference count to zero, and thus delete the object as well.
There is no way that wx could automatically manage your objects using reference counts if you are using pointers in the way you are. Perhaps you want to use the copy constructor, and stop using manual memory handling? C++ has the RAII technique - use it.
Lastly, can I ask why m_default_image is a pointer? You're just making life hard for yourself by using raw pointers all the time.
To add to Arafangion's answer (and I would just comment if I had enough rep points to do so), if you read the documentation for wxDELETE(), you would have seen that it actually says:
This function uses operator delete to free the pointer and also sets it to NULL.
C++ pointers don't have anything to do with the implementation of reference counting in wxWidgets (and I don't think it does anywhere else except when using smart pointers), and as wxDELETE is meant to be used with pointers, it also has absolutely nothing to do with reference counting except that it deleted an object that may or may not have been reference counted, and if it was, and the objects reference count was more than 1, the object really wasn't deleted, however, your pointer was still invalidated.
Reference counting is used internally by wxImage objects meaning that you can copy them cheaply as the underlying image data is shared. It is not exposed in wx API and definitely doesn't have anything to do with wxImage pointers.