1

Is there any way to tell the Java VM (for this case, HotSpot or Zing) to no longer treat an objects as if there is a finalize method? Really, the whole class, I'm guessing, if at all possible.

I'm having problems with objects that have already had their resources freed but still put pressure on the VM that thinks it needs to call finalize on them.

This is in a library, so there is no way to change the class.

The use case is a library was written to clean up off-heap resources if you forgot or decided to let the GC do it for you. The problem is I get a lot of them hanging around.

JasonN
  • 1,339
  • 1
  • 15
  • 27

3 Answers3

3

Your only option would be to use an agent (-javaagent) that will override the finalize implementation with an empty one. The JVM automatically creates a FinalReference object for each instance of a class with non-empty finalize (and this is how the JVM (Oracle) tracks the finalizable objects). You can't change his behavior.

Shimi Bandiel
  • 5,773
  • 3
  • 40
  • 49
  • I was thinking along that line: a custom loader that removed the finalize method on load, but I really don't want to get that in depth. I've never worked with the agent stuff, just some bytecode rewriting, and I think I can hack around it at a higher level for this particular app. – JasonN Apr 21 '16 at 15:10
1

The use case is a library was written to clean up off-heap resources if you forgot or decided to let the GC do it for you.

For that we use a Cleaner as ByteBuffer does. This is more light weight way of cleaning up resources.


EDIT Another option is you could

  • obtain the Finalizer.queue and remove elements yourself while holding the Finalizer.lock You could add a thread which periodically cleans up the queue of elements which don't need to be there.
  • you could replace this queue with your own implementation so it behaves differently. e.g. not add objects of a chosen class in the first place.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • There is one of those, but there is also a `finalize()` method that basically does the same thing. The cleaner in this case, recycles it into and object pool. (FYI, this is a combination of Tibrv suckage and another library we are using - I have src to the second library, but changing it is ugly). – JasonN Apr 21 '16 at 15:06
  • @JasonN in theory, the header records whether a finalize() has already been called on an object and prevents it being called a second time. You could try setting this prematurely. – Peter Lawrey Apr 21 '16 at 15:21
  • that is actually an interesting idea. I wonder if it would eliminate the GC issues though, or would I still end up with half a million objects waiting around to be skipped over. – JasonN Apr 21 '16 at 15:31
  • 1
    After some thought, I think that playing with the finalize flag probably won't work. It still going to sit in the finalizer lists for two GC passes regardless. This just prevents Java from calling `finalize()` if the object is resurrected. – JasonN Apr 21 '16 at 19:12
  • @JasonN I would have thought this would prevent it being added to the queue in the first place. – Peter Lawrey Apr 21 '16 at 19:22
  • You're probably right. Since there is no way to re-resurrect and object twice, that would make sense. – JasonN Apr 21 '16 at 19:24
  • and that other option is completely awesome. – JasonN Apr 22 '16 at 16:18
0

No, you can't do this. It's part of the JVM spec. Nor is it clear why you should do this; the VM will call finalize() if they have that method when they're cleaned up, regardless of what has happened previously. If you're calling finalize directly and triggering some kind of double finalize bug, then the answer is simple: "Don't do that"

AlBlue
  • 23,254
  • 14
  • 71
  • 91
  • The use case is a library was written to clean up off-heap resources if you forgot or decided to let the GC do it for you. It isn't a bug, but no VM handles finalize or WeakRefs well and my VM has 500k of them sitting around. The general strategy is to not use them, ever. Ever ever ever, when latency matters. Since this is a library, I have no way of turning this off. Maybe I can do some monkey patching the class file at load time, but I was hoping for an easier solution. – JasonN Apr 21 '16 at 14:58