5

When someone is making bindings from a C library to Java (or any other garbage-collected language without destructors that are guaranteed to run), how do they deal with proper deallocation of non-garbage-collected memory?

EDIT: What I'm thinking of (I know this isn't explicitly state in my original question) is when a piece of non-gc'ed memory holds references to other non-gc'ed resources that need to be freed when that object is freed. For example, if you have a non-gc'ed linked list node that is the head of a long list of such nodes and you want to have the gc system clean it up automatically eventually, how do you set that up?

compman
  • 2,174
  • 2
  • 18
  • 26
  • possible duplicate of [Is there a destructor for Java?](http://stackoverflow.com/questions/171952/is-there-a-destructor-for-java) – Raedwald Apr 23 '15 at 06:02

3 Answers3

2

They typically provide APIs to create and release a reference.

For example, Java's Native Interface provides global references that allow pinning an Java object in memory until the C program is done with it via NewGlobalRef and DeleteGlobalRef

NewGlobalRef Creates a new global reference to the object referred to by the obj argument. The obj argument may be a global or local reference. Global references must be explicitly disposed of by calling DeleteGlobalRef()

and it also provides local refs that only last as long as Java has handed over control to C for:

Local references are valid for the duration of a native method call. They are freed automatically after the native method returns.

The JVM embedding API provides a similar mechanism which allows pinning of an object in memory until the C program determines it is done with it.

Python's C extension API provides a similar API to the JNI.

A borrowed reference can be changed into an owned reference by calling Py_INCREF().

The owner of a reference is responsible for calling Py_DECREF() when the reference is no longer needed.

The python names reflect the fact that python uses reference counting* but the API is basically the same as that in JNI which is based on a non-ref counting garbage collector -- you have one function that pins a region of memory managed by the interpreter and one that releases a previously pinned region back to the interpreter.

* - python isn't a true ref-counting approach. From the same page "While Python uses the traditional reference counting implementation, it also offers a cycle detector that works to detect reference cycles."

Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
2

In java, you have the finalize() concept. You can free the C-memory there.

However, probably a better way is to use PhantomReferences along with a ReferenceQueue. You can extend the PhantomReference class so that it holds some id or pointer or whatever to the C-side memory you need to free. When it is enqueued in the ReferenceQueue, you can then free the C-side memory that this id points to - the Java object is guaranteed to not be in existence "in Java" anymore.

stolsvik
  • 5,253
  • 7
  • 43
  • 52
  • They changed how javadoc pages look. – compman Aug 03 '11 at 17:47
  • 1
    Is Java's finalize() guaranteed to be run before a Java object is freed (if it ever is)? – compman Aug 03 '11 at 17:50
  • "The general contract of finalize is that it is invoked if and when the JavaTM virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized. The finalize method may take any action, including making this object available again to other threads; the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded." – stolsvik Aug 03 '11 at 18:41
  • Do note that the Reference and ReferenceQueue concept offers much better "communication" with the GarbageCollector than finalize(). – stolsvik Aug 03 '11 at 18:43
  • 1
    Yes, "finalize()" is run before the object is freed. The problem is that you can't determine WHEN, or IF, this will ever happen. – paulsm4 Aug 03 '11 at 18:45
  • Is there any method that the garbage collector calls when a PhantomReference is enqueued? The enqueue method isn't called by the garbage collector. – compman Aug 04 '11 at 14:55
0

When using bindings with languages such as Java, the other language machine holds reference counters for each allocated object. The API should give methods to increase or decrease theses counters to indicate the machine that your C program holds reference to the other machine objects. If C program does not have references to a given object, the reference counter may reach 0 and the other language machine will be free to garbage collect it. However, you may not be able to ask the machine to release a given object.

neodelphi
  • 2,706
  • 1
  • 15
  • 22