Suppose in java, I want to do some operations when an array (e.g., int[] a = new int[3]
) is garbage-collected. I know there is a finalize
methods for Objects. But is there a "finalize" method for arrays?

- 811
- 5
- 18
-
It would inherit `Object.finalize()`, but there is no way to override it. Have a look into `WeakReferences` with a reference queue. – user207421 Mar 19 '21 at 05:17
-
1Could you explain why you want to do that? There are very few use cases for `finalize` so if you can provide some information on what you are trying to achieve there's likely to be another way to achieve it. – sprinter Mar 19 '21 at 05:47
-
can you use at least java-9? – Eugene Mar 21 '21 at 18:24
2 Answers
finalizers in their entirety are obsolete.
The ReferenceQueue system replaces it and can do this.
But please be aware that garbage collection often never even happens. The VM will shut down before it ever runs out of memory. There is no guarantee that an array that is no longer reachable, is going to be removed in a few moments. It may take days. Or it really will only take a moment. You don't get guarantees.

- 85,357
- 5
- 51
- 72
-
1Even worse, garbage collection can happen earlier than expected. [This issue](https://stackoverflow.com/q/46971788/2711488) is exactly the result of an array cleanup in a finalizer. There’s also [this similar issue](https://stackoverflow.com/q/58714980/2711488) (though not about an array). – Holger Mar 19 '21 at 08:53
-
GC _too soon_, that's a new one. Thank you for the links, @Holger, those are excellent cases in point. OP, I'd read them - they provide good insights in the difficulties you may run into when using finalizers/refqueues. – rzwitserloot Mar 19 '21 at 13:01
If you can use java-9
and up, there is the cleaner API that you can use. You need to carefully read the documentation so that (and the apiNote
) you do not step on an obvious mistake :
The cleaning action is invoked only after the associated object becomes phantom reachable, so it is important that the object implementing the cleaning action does not hold references to the object
Also you need to create a wrapper around your array
, but otherwise it is pretty doable. Here is an example emulating that:
public static void main(String[] args) {
ArrayWrapper wrapper = new ArrayWrapper(new int[]{1,2,3});
wrapper = null;
gc();
System.out.println("Done");
}
static void gc() {
for(int i=0;i<3;++i){
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100));
System.gc();
}
}
static class ArrayWrapper implements AutoCloseable {
private static final Cleaner CLEANER = Cleaner.create();
private final Inner inner;
private final Cleaner.Cleanable cleanable;
public ArrayWrapper(int[] array) {
this.inner = new Inner(array);
cleanable = CLEANER.register(this, inner);
}
public int[] getArray() {
return inner.array;
}
@Override
public void close() {
System.out.println("close called");
cleanable.clean();
}
static class Inner implements Runnable {
private final int [] array;
public Inner(int[] array) {
this.array = array;
}
@Override
public void run() {
System.out.println("Run called");
}
}
}
When running this, I get:
Run called
Done
which basically tells you that once wrapper
is garbaged collected, it runs the action in Inner
(that is a Runnable
).
Notice that ArrayWrapper
also implements AutoCloseable
, so that you could use it in try with resource
constructs, if your code allows it. That would be far simpler, too; if you wanted to achieve something like : "when wrapper goes out of scope, do some action in close method".

- 117,005
- 15
- 201
- 306
-
1You are only proving that the `ArrayWrapper` got garbage collected. Since the array might be still in use by that time, it’s a highly dangerous thing. Not to speak of the concurrent access to the array that might happen if the cleaner truly does something with the array. We don’t even know why the OP thinks they needed this and you’ve just demonstrated how easy it is to do it wrong. – Holger Mar 22 '21 at 09:40
-
@Holger indeed! what if in theory the OP has a valid case, then I can see this being possible only via an explicit `ReferenceQueue`. Is it possible to do with via `Cleaner` may be? what do you think? – Eugene Mar 22 '21 at 16:04