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

12.1.0 - Allow configuring minimum size before File Mapped Buffers are used. #12701

Open
joakime opened this issue Jan 10, 2025 · 5 comments
Open
Assignees

Comments

@joakime
Copy link
Contributor

joakime commented Jan 10, 2025

Jetty version(s)
12.1.0

Enhancement Description

There are several places we use the FileChannel.map() feature to load File as a memory mapped ByteBuffer.

The javadoc for this method indicates the following memory concern ...

"For most operating systems, mapping a file into memory is more expensive than reading or writing a few tens of kilobytes of data via the usual read and write methods. From the standpoint of performance it is generally only worth mapping relatively large files into memory."

The enhancement is that there should be a configurable minimum size before a memory mapped ByteBuffer is used, vs a normal ByteBuffer from typical file I/O operations.

Discovered as part of issue #12695

@arsenalzp
Copy link
Contributor

If no objections, I would like to support on solving of this issue.

@arsenalzp
Copy link
Contributor

Please assign it to me. Thank you!

@olamy
Copy link
Member

olamy commented Jan 31, 2025

Please assign it to me. Thank you!

done. Feel free to propose a PR. Thanks!

@arsenalzp
Copy link
Contributor

arsenalzp commented Feb 5, 2025

I'm wondering what is relatively large files from jetty point of view?

I did a benchmark tests in SampleTime mode (JMH).
There are 3 files which were being mapped:

10485760000 jumbo
1048576000 large
104857600 medium
1024000 small

Here is a sample of the benchmark method:

@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void mapLargeFile(Blackhole bh) throws IOException 
{
    bh.consume(channelLarge.map(FileChannel.MapMode.READ_ONLY, 0, channelLarge.size()));
}

Result is:

Benchmark                              Mode     Cnt    Score   Error  Units
BenchmarkTest.mapJumboFile           sample  190598    0.009 ± 0.004  ms/op
BenchmarkTest.mapJumboFile:p0.00     sample            0.003          ms/op
BenchmarkTest.mapJumboFile:p0.50     sample            0.005          ms/op
BenchmarkTest.mapJumboFile:p0.90     sample            0.008          ms/op
BenchmarkTest.mapJumboFile:p0.95     sample            0.010          ms/op
BenchmarkTest.mapJumboFile:p0.99     sample            0.021          ms/op
BenchmarkTest.mapJumboFile:p0.999    sample            0.362          ms/op
BenchmarkTest.mapJumboFile:p0.9999   sample            4.487          ms/op
BenchmarkTest.mapJumboFile:p1.00     sample          129.761          ms/op
BenchmarkTest.mapLargeFile           sample  195990    0.008 ± 0.003  ms/op
BenchmarkTest.mapLargeFile:p0.00     sample            0.004          ms/op
BenchmarkTest.mapLargeFile:p0.50     sample            0.005          ms/op
BenchmarkTest.mapLargeFile:p0.90     sample            0.008          ms/op
BenchmarkTest.mapLargeFile:p0.95     sample            0.009          ms/op
BenchmarkTest.mapLargeFile:p0.99     sample            0.017          ms/op
BenchmarkTest.mapLargeFile:p0.999    sample            0.371          ms/op
BenchmarkTest.mapLargeFile:p0.9999   sample            1.462          ms/op
BenchmarkTest.mapLargeFile:p1.00     sample          145.752          ms/op
BenchmarkTest.mapMediumFile          sample  182018    0.009 ± 0.003  ms/op
BenchmarkTest.mapMediumFile:p0.00    sample            0.004          ms/op
BenchmarkTest.mapMediumFile:p0.50    sample            0.005          ms/op
BenchmarkTest.mapMediumFile:p0.90    sample            0.009          ms/op
BenchmarkTest.mapMediumFile:p0.95    sample            0.011          ms/op
BenchmarkTest.mapMediumFile:p0.99    sample            0.020          ms/op
BenchmarkTest.mapMediumFile:p0.999   sample            0.369          ms/op
BenchmarkTest.mapMediumFile:p0.9999  sample            1.460          ms/op
BenchmarkTest.mapMediumFile:p1.00    sample          173.539          ms/op
BenchmarkTest.mapSmallFile           sample  212882    0.008 ± 0.003  ms/op
BenchmarkTest.mapSmallFile:p0.00     sample            0.004          ms/op
BenchmarkTest.mapSmallFile:p0.50     sample            0.004          ms/op
BenchmarkTest.mapSmallFile:p0.90     sample            0.007          ms/op
BenchmarkTest.mapSmallFile:p0.95     sample            0.009          ms/op
BenchmarkTest.mapSmallFile:p0.99     sample            0.013          ms/op
BenchmarkTest.mapSmallFile:p0.999    sample            0.301          ms/op
BenchmarkTest.mapSmallFile:p0.9999   sample            1.400          ms/op
BenchmarkTest.mapSmallFile:p1.00     sample          171.704          ms/op

By the way, it is not possible to map a region which size is greater than Integer.MAX_VALUE.

So, question: is it worth to implement this feature?

@arsenalzp
Copy link
Contributor

Hello colleagues,

@joakime @olamy do you need modification yet?
As I don't see any differences in time consuming between file size mapping.
If you want me to implement this feature, then let's discuss which file size is the limiting one for memory mapping.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

3 participants