RFR: JDK-8337974 - ChannelInputStream::skip can use splice (linux) [v3]
Markus KARG
duke at openjdk.org
Sun Jan 26 15:54:53 UTC 2025
> # Targets
>
> The major target of this issue is to reduce execution time of `ChannelInputStream::skip(long)`. In particular, make `skip(n)` run noticable faster than `read(new byte[n])` on pipes and sockets in the optimal case, but don't run noticable slower in the worst case.
>
> A side target of this issue is to provide unit testing for `ChannelInputStream::skip(long)`. In particular, provide unit testing for files, pipes and sockets.
>
> An appreciated benefit of this issue is reduced resource consumption (in the sense of CPU cycles, Java Heap, power consumption, CO2 footprint, etc.) of `ChannelInputStream::skip(long)`. Albeit, as it is not a target, this was not acitvely monitored.
>
>
> # Non-Targets
>
> It is not a target to improve any other methods of the mentioned or any other class. Such changes should go in separate issues.
>
> It is not a target to add any new *public* APIs. The public API shall be kept unchanged. All changes implied by the current improvement shall be purely *internal* to OpenJDK.
>
> It is not a target to improve other source types besides pipes and sockets.
>
>
> # Description
>
> What users expect from `InputStream::skip`, besides comfort, is "at least some" measurable benefit over `InputStream::read`. Otherwise skipping instead of reading makes no sense to users.
>
> For files, OpenJDK already applies an effective `seek`-based optimization. For pipes and sockets, benefits were neglectible so far, as `skip` more or less was simply an alias for `read`.
>
> Hence, this issue proposes optimized implementations for `ChannelInputStream::skip` in the pipes and sockets cases.
>
>
> # Implementation
>
> The abstract idea behind this issue is to prevent transmission of skipped data into the JVM's on-heap memory in the pipes and socket cases. As a Java application obviously is not interested in skipped data, copying it into the Java heap is a waste of both, time and heap, and induces (albeit neglectible) GC stress without any benefit.
>
> Hence, this pull request changes the implementation of `ChannelInputStream::skip` in the following aspects:
> 1. On *all* operating systems, for pipe and socket channels, `skip` is implemented in C. While the data *still is* transferred form the source into the OS kernel and from the OS kernel into the JVM's off-heap memory, it is *not* transferred into the JVM's on-heap memory.
> 2. For *Linux* pipes only, `splice` is used with `/dev/null` as the target. Data is neither transferred from the source into the OS kernel, nor from the OS kernel into n...
Markus KARG has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains four commits:
- Socket.getInputStream()'s JavaDocs explain behavior of skip for timeout, non-blocking, interrupt
- Removed trailing whitespace
- Corrected issue ID: 8337974
- JDK-8337974 Implementing ChannelInputStream::skip using splice on Linux and C-loops elsewhere
-------------
Changes: https://git.openjdk.org/jdk/pull/20489/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=20489&range=02
Stats: 1186 lines in 21 files changed: 1179 ins; 0 del; 7 mod
Patch: https://git.openjdk.org/jdk/pull/20489.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/20489/head:pull/20489
PR: https://git.openjdk.org/jdk/pull/20489
More information about the nio-dev
mailing list