Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from Finalize to Cleaners #978

Open
re-thc opened this issue Jun 26, 2018 · 5 comments
Open

Switch from Finalize to Cleaners #978

re-thc opened this issue Jun 26, 2018 · 5 comments

Comments

@re-thc
Copy link
Contributor

re-thc commented Jun 26, 2018

See https://stackoverflow.com/questions/48533097/in-java9-finalizers-have-been-deprecated-instead-cleaners-have-been-introduced for more information. Finalizers are deprecated and likely removed in a future version of Java. Cleaners are also more efficient.

@matthiasblaesing
Copy link
Member

Actually the second answer in the stack overflow is more interesting: Use try-with-resource. I see this as combineable with cleaners.
If you want to work on it, I'm certainly willing to help and support the work.

@joerg1985
Copy link
Contributor

I had a look at the code and i think there are several things to consider, it is not like a drop in replacement:

  • Increased minimum Java version
    Using Cleaners will raise the bar from 1.4 to Java 9, this is a huge jump. The Closeable interface needed for try-with-resource will increase the level to 1.5, this should be okay.
  • Breaking changes is the API
    Currently there are alot of places where the finalize calls a public / protected dispose method. I think this not possible using Cleaners, the cleaning action is not allowed to keep a reference to the associated object, see. This will break the API in many areas e.g. FileMonitor, ObjectFactory, ProxyObject and more classes.
  • The state needs to be tracked outside the associated object
    This will increase the number of objects / memory allocated, e.g. each Memory instance will create its state object.

Are Cleaners realy needed to get rid of the finializers? A custom implementation with Thread / ReferenceQueue / PhantomReference should do the same, without raising the Java version to high and it might be possible to find solutions to the other points too. (Not sure if this is working: instead of keeping a state object, keep a counterpair object to detect the phantom state and call dispose)

I will give it a try, but it might take some days to have a working example.

@dbwiddis
Copy link
Contributor

We're currently at 1.6. The try-with-resources syntax was introduced in 1.7. There is zero chance that we will move past 1.8 in the near term.

@joerg1985
Copy link
Contributor

Implementing a custom cleaner seems to be easy. It is just a loop in a deamon thread, querying a reference que, calling the cleaning action.

Changing to a cleaner like approach will break the API in all affected classes, the dispose/disposeAll methods are currently not private and might be overwritten. The cleaning action is not allowed to keep a reference to the associated object, this makes it impossible to call dispose/disposeAll. Keeping a reference to the associated object, will avoid the object getting phantom reachable and getting cleaned.

@primetomas
Copy link

We just hit an use-after-free issue using Memory.java, which got me attracted to this issue (bug in the using library not in JNA so no complaints). An API change eventually if finalize is removed seems inevitable, but definitely doable for us. We are on Java 8 or Java 11 right now, and will have to support the next LTS java version (hope finalize is not removed yet then :-)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants