-1

I have a Java program which calls into my C++ library. JNI-C++ bridging is created using SWIG
I am relatively new to Java & trying to understand the behavior of System.gc & System.runFinalization
This code below causes a SIGABRT, killing my app (2 out of 10 runs)

public static void main (String[] args)
{
    try
    {
        doSomeStuff();
    } catch(Exception ex)
    {
        System.out.println(ex.getMessage());
    } finally {
        System.runFinalization();
        System.gc();
    }

}

void doSomeStuff()
{
    try
    {
        sampleCppClass cppClass = new sampleCppClass();
        /*
        *   do some stuff with Cpp obj
        */
    } catch (Exception ex)
    {
        System.out.println(ex.getMessage());
    } finally {
        System.runFinalization();
        System.gc();
    }
}


Whereas this one works fine

public static void main (String[] args)
{
    try
    {
        doSomeStuff();
    } catch(Exception ex)
    {
        System.out.println(ex.getMessage());
    } finally {
        System.runFinalization();
        System.gc();
    }

}

void doSomeStuff()
{
    try
    {
        sampleCppClass cppClass = new sampleCppClass();
        /*
        *   do some stuff with Cpp obj
        */
    } catch (Exception ex)
    {
        System.out.println(ex.getMessage());
    } 
}


I know that System.gc() & System.runFinalization() are non-deterministic(Source-1, Source-2 and Source-3).
Can it so happen that the System.gc() in doSomeStuff gets executed & free's the obj.
Later on, the System.gc() in main runs & tries to free the same obj causing a crash? If this is indeed the case, is there a way to prove it (logs/prints to show the order of object free'ed by gc)?
This SO post, explains causes of SIGABRT
Since I am running in release mode, my C++ lib doesnt have any assert/abort. Hence I am concerned about double/multiple free's of the object in consideration.

Community
  • 1
  • 1
Ganesh kudva
  • 990
  • 3
  • 13
  • 34
  • No. Because `System.gc()` is only advisory (the JVM may do something, or it may ignore it). – Elliott Frisch Aug 15 '16 at 22:40
  • No, because the object is only released once, and because `System.gc()` may not release it at all. – user207421 Aug 15 '16 at 22:42
  • Hi @ElliottFrisch and EJP, Thanks for the response. Can you suggest what else may cause **SIGABRT** in my app? As already mentioned my C++ lib doesnt have **assert/abort** and having only one call to **System.gc()** in main func, seems to solve the issue. – Ganesh kudva Aug 15 '16 at 22:52
  • 1
    You seem to have asked the wrong question here. I suggest you start again. But your code doesn't make any sense. You would call `runFinalization()` *after* `gc()`, not before. I would just remove both calls throughout. I haven't used them for decades. I suggest that `SimpleCPPClass` has JNI code in it, and that that is where you should be looking. – user207421 Aug 15 '16 at 22:55

1 Answers1

1

Can it so happen that the System.gc() in doSomeStuff() gets executed & free's the obj.

Yes, but it can also happen that it doesn't do anything.

Later on, the System.gc() in main runs & tries to free the same obj causing a crash?

No. Ths is garbage collection, not C++ destruction. It only happens once per object, or indeed never.

The underlying reason for your problem as far as this code is concerned is that you have your gc() and runFinalization() calls in the wrong order. runFinalization() does nothing if there has been no prior GC. It executes the finalizer queue, which is only populated by GC.

So when you do it all twice, only the second runFinalization() does anything. This presumably executes a finalizer in your SampleCPPClass, which appears to have a bug, evidently in native code.

But as you haven't posted the code concerned it is impossible to comment further.

user207421
  • 305,947
  • 44
  • 307
  • 483