You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by ya...@apache.org on 2023/10/14 12:01:42 UTC
[spark] branch master updated: [SPARK-45530][CORE] Use `java.lang.ref.Cleaner` instead of `finalize` for `NioBufferedFileInputStream`
This is an automated email from the ASF dual-hosted git repository.
yangjie01 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 30d95703ddd [SPARK-45530][CORE] Use `java.lang.ref.Cleaner` instead of `finalize` for `NioBufferedFileInputStream`
30d95703ddd is described below
commit 30d95703ddd66a96dc2ddaae9ca38900583544fe
Author: yangjie01 <ya...@baidu.com>
AuthorDate: Sat Oct 14 20:01:20 2023 +0800
[SPARK-45530][CORE] Use `java.lang.ref.Cleaner` instead of `finalize` for `NioBufferedFileInputStream`
### What changes were proposed in this pull request?
This pr change to use `java.lang.ref.Cleaner` instead of `finalize()` for `NioBufferedFileInputStream`. They are all protective measures for resource cleanup, but the `finalize()` method has been marked as `deprecated` since Java 9 and will be removed in the future, `java.lang.ref.Cleaner` is the more recommended solution.
https://github.com/openjdk/jdk/blob/dfacda488bfbe2e11e8d607a6d08527710286982/src/java.base/share/classes/java/lang/Object.java#L546-L568
```
* deprecated The finalization mechanism is inherently problematic.
* Finalization can lead to performance issues, deadlocks, and hangs.
* Errors in finalizers can lead to resource leaks; there is no way to cancel
* finalization if it is no longer necessary; and no ordering is specified
* among calls to {code finalize} methods of different objects.
* Furthermore, there are no guarantees regarding the timing of finalization.
* The {code finalize} method might be called on a finalizable object
* only after an indefinite delay, if at all.
*
* Classes whose instances hold non-heap resources should provide a method
* to enable explicit release of those resources, and they should also
* implement {link AutoCloseable} if appropriate.
* The {link java.lang.ref.Cleaner} and {link java.lang.ref.PhantomReference}
* provide more flexible and efficient ways to release resources when an object
* becomes unreachable.
*
* throws Throwable the {code Exception} raised by this method
* see java.lang.ref.WeakReference
* see java.lang.ref.PhantomReference
* jls 12.6 Finalization of Class Instances
*/
Deprecated(since="9")
protected void finalize() throws Throwable { }
```
### Why are the changes needed?
Clean up deprecated api usage
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Pass GitHub Actions
### Was this patch authored or co-authored using generative AI tooling?
No
Closes #43333 from LuciferYang/nio-buffered-fis-cleaner.
Lead-authored-by: yangjie01 <ya...@baidu.com>
Co-authored-by: YangJie <ya...@baidu.com>
Signed-off-by: yangjie01 <ya...@baidu.com>
---
.../spark/io/NioBufferedFileInputStream.java | 34 ++++++++++++++++++----
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/core/src/main/java/org/apache/spark/io/NioBufferedFileInputStream.java b/core/src/main/java/org/apache/spark/io/NioBufferedFileInputStream.java
index 91910b99ac9..441587cf735 100644
--- a/core/src/main/java/org/apache/spark/io/NioBufferedFileInputStream.java
+++ b/core/src/main/java/org/apache/spark/io/NioBufferedFileInputStream.java
@@ -18,6 +18,8 @@ import org.apache.spark.storage.StorageUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.lang.ref.Cleaner;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
@@ -32,8 +34,11 @@ import java.nio.file.StandardOpenOption;
*/
public final class NioBufferedFileInputStream extends InputStream {
+ private static final Cleaner CLEANER = Cleaner.create();
private static final int DEFAULT_BUFFER_SIZE_BYTES = 8192;
+ private final Cleaner.Cleanable cleanable;
+
private final ByteBuffer byteBuffer;
private final FileChannel fileChannel;
@@ -42,6 +47,7 @@ public final class NioBufferedFileInputStream extends InputStream {
byteBuffer = ByteBuffer.allocateDirect(bufferSizeInBytes);
fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
byteBuffer.flip();
+ this.cleanable = CLEANER.register(this, new ResourceCleaner(fileChannel, byteBuffer));
}
public NioBufferedFileInputStream(File file) throws IOException {
@@ -125,13 +131,29 @@ public final class NioBufferedFileInputStream extends InputStream {
@Override
public synchronized void close() throws IOException {
- fileChannel.close();
- StorageUtils.dispose(byteBuffer);
+ try {
+ this.cleanable.clean();
+ } catch (UncheckedIOException re) {
+ if (re.getCause() != null) {
+ throw re.getCause();
+ } else {
+ throw re;
+ }
+ }
}
- @SuppressWarnings("deprecation")
- @Override
- protected void finalize() throws IOException {
- close();
+ private record ResourceCleaner(
+ FileChannel fileChannel,
+ ByteBuffer byteBuffer) implements Runnable {
+ @Override
+ public void run() {
+ try {
+ fileChannel.close();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ } finally {
+ StorageUtils.dispose(byteBuffer);
+ }
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org