Closed joakime closed 1 year ago
After a conversation with @sbordet we are going to use the Java 9+ JVM feature java.lang.ref.Cleaner
on Jetty 10+ to cleanup temp files in FileBufferedHandler
properly for all OS's, including Linux.
@joakime @sbordet I think we already looked into doing this before and determined it was not possible, see issue #6046.
@sbordet and I tested this, we think we have a solution specific for FileBufferedInterceptor, but only on Jetty 10.0.x+
@lachlan-roberts in #6046 I wanted to deallocate the memory explicitly by invoking an API.
This is what sun.misc.Cleaner.clean()
was doing for e.g. DirectByteBuffer
.
However, turns out that java.lang.ref.Cleanable.clean()
has a completely different semantic and it's not possible to use it for #6046.
However, it is possible to do unrelated actions (such as close a File
), which is what @joakime is doing to fix this issue.
@sbordet And we can't just do this in the callback because the MappedByteBuffer
s are somehow holding the file open until they are garbage collected?
How about we just don't use filemapped buffers on windows?
@sbordet And we can't just do this in the callback because the
MappedByteBuffer
s are somehow holding the file open until they are garbage collected?
Correct.
With sun.misc.Cleaner.clean()
we could have released the mapped buffer immediately, but we cannot use the API, not even via reflection (due to JPMS).
With java.lang.ref.Cleanable.clean()
we have to wait for the GC to release the mapped buffer, and then we can close the file.
How about we just don't use filemapped buffers on windows?
Not a bad idea 😃
How about we just don't use filemapped buffers on windows?
That would mean everywhere we currently use BufferUtil.toMappedBuffer
would need to be reviewed.
In jetty-10.0.x
, that's a short list ...
org.eclipse.jetty.server.CachedContentFactory
org.eclipse.jetty.server.handler.FileBufferedResponseHandler
We also have usages of java.nio.channels.FileChannel.map()
directly to review.
Opened PR #6588 to show proposal of usage.
One wart I don't like, is if the JVM closes before the phantom reference is reached, the registered action does not seem to execute.
@joakime You could work around that problem by restricting the mechanism to only deleting files instead of executing any random job and completing it with File.deleteOnExit
.
But I'm not fond of this idea, I think any mechnism that relies on the GC to manage OS resources is doomed to fail soon or late, so I'd rather invest time in Greg's proposal of not using file mapped buffers anymore.
Postponing to 10.0.10
This issue has been automatically marked as stale because it has been a full year without activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been closed due to it having no activity.
Jetty version(s) 9.4.x - HEAD
Java version/vendor
(use: java -version)
Java 8u292 and 11.0.1OS type/version Windows 10
Description The FileBufferedInterceptor.dispose() attempts to clean up files it has recently used. However, this is not possible currently on windows, as it will throw a AccessDeniedException due to the fact that the file is currently locked.
We need to verify that we properly close the various file handles and resources for these files before we call dispose.
How to reproduce? Run the build / test on windows 10.