2

I have global static registry in my class, which registering instances in some circumstances. Actually it does not depend on garbage collecting, but some functionality is obviously placed in finalize().

During jUnit test I wish to test how this functionality works, but I can't call GC by force. I am calling gc() in my tearDown()

@After
public void tearDown() throws Exception {

    log.debug("tearDown()");

    a = null;
    b = null;
    c = null;
    d = null;
    e = null;
    f = null;
    g = null;

    System.gc();

    log.debug("asserting hash size");
    assertEquals(0, Myclass.getRegisterSize());
}

but this does not help. I see in log that asserting message appears before finalizing.

Is it possible to wait until all finalizations occur?

Are there any other means, for example to restart classloader or flush heap or something in jUnit? I mean to do everything from scratch?

Suzan Cioc
  • 29,281
  • 63
  • 213
  • 385
  • it is possible that finalization of objects never occurs, and shouldn't be depended on. go see http://stackoverflow.com/questions/2506488/java-finalize-method-call – VolatileDream Oct 30 '12 at 19:57
  • Okey, so how to drop entire memory or something? – Suzan Cioc Oct 30 '12 at 20:05
  • The closest thing to what you want to do would be `System.gc(); System.runFinalization();` which may or may not do anything, as they are both suggestions to the JVM ( see http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#gc() ). – VolatileDream Oct 30 '12 at 20:09
  • 1
    The thing to do is redesign your project until you're _not_ depending on finalization. There's a reason finalization and other static state is so frowned upon. – Louis Wasserman Oct 30 '12 at 20:18
  • 1
    I suppose your nullyfying the obejcts is more than enough that you can do. You are taking good care of them. Don't bother about gc(), coz it'll run at it's own time. – Arham Oct 30 '12 at 20:21
  • @Louis I know finalization contras, but here I need it. – Suzan Cioc Oct 30 '12 at 20:25

5 Answers5

2

If you are overriding finalize why not just call it directly. Currently finalize is protected but your subclass could make it public. Then you can call it directly and check what is being called in there. Tests should be deterministic so you want it to run everytime. Relying on the garbage collector could bring inconsistencies to your tests as you cannot guarantee what/when it is being called

RNJ
  • 15,272
  • 18
  • 86
  • 131
1

Not, it isn't possible to wait for all finalizations to occur. They may not happen at all. Finalize gets run when the object is garbage collected. Some objects will never get collected, for instance a Main class. This doesn't get garbage collected because the JVM exits before it runs the gc().

The best idea (really) is to add a method which does the cleaning up and then call it from your JUnit test. And, if you really, really need to, from finalize() as well. But you can never depend upon finalize() being called.

Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
0

The first rule of writing tests is to write testable code. Finalization is very hard to test, unless you can test design a test that monitors the effects of the finalization.

In general, you can trust finalize() to eventually get called, so you might not need to test this functionality in particular, and instead test whatever methods are called by the finalize() method. Either that, or extend your classes to allow the test code to inject some object that will be modified by the finalize() method.

It is either that, or simply call the finalize()-method directly from your test code.

Joel Westberg
  • 2,656
  • 1
  • 21
  • 27
0

Looks like you are trying to test "finalize" feature of JVM - you shouldn't to. What can work here - is moving the code you want to test to a separate method and writing a simple unit-test as usually.

Andrey Mormysh
  • 809
  • 5
  • 12
0

From the posted code, you are setting null to the References to the objects in your junit test, not on the class your running the assertion against. So MyClass will still have the objects referenced.

Tinman
  • 786
  • 6
  • 18