问题标签 [zero-copy]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
2666 浏览

java - FileChannel zero-copy transferTo fails to copy bytes to SocketChannel

I'm seeing some strange behavior when transferring large files from file to socket using zero-copy in Java. My environments:

  • Windows 7 64-bit JDK 1.6.0_45 and 1.7.0_79.
  • Centos 6.6 64-bit JDK 1.6.0_35

What the program does: client copies an input file into a socket, and server copies socket to output file using zero-copy methods: transferFrom and transferTo. Not all bytes are reaching the server if file size is relatively large, 100Mb+ in case of Windows and 2GB+ in case of Centos. Client and server reside on the same machine and localhost address is used to transfer data.

The behavior is different depending on OS. On Windows, the client completes transferTo method successfully. The number of transferred bytes is equal to input file size.

long bytesTransferred = fileChannel.transferTo(0, inputFile.length(), socketChannel);

The server on the other hand, reports a lower number of received bytes.

long transferFromByteCount = fileChannel.transferFrom(socketChannel, 0, inputFile.length());

On Linux bytesTransferred on client is 2Gb even if input file size is 4Gb. There is sufficient space on both configurations.

On Windows I was able to transfer a 130Mb file with the one of the following workarounds: 1) increasing receive buffer size on server and 2) adding thread sleep method in client. This leads me to think that transferTo method on the client completes when all bytes are sent to socket send buffer, not to server. Whether or not those bytes make it to server is not guaranteed, which creates problems for my use case.

On Linux maximum file size that I'm able to transfer with a single transferTo invocation is 2Gb, however at least the client reports a correct number of bytes sent to server.

My questions: what's the best way for the client to ensure guaranteed delivery of the file to the server, cross-platform? What mechanisms are used to emulate sendfile() on Windows?

Here's the code:

Client - ZeroCopyClient.java:

Server - ZeroCopyServer.java:

UPDATE 1: Linux code fixed with loop.

UPDATE 2: One possible workaround I'm considering requires client-server cooperation. At the end of transmission the server writes the length of received data back to client which the client reads it in blocking mode.

Server responds:

The client blocks with read:

As a result, the client waits for the bytes to pass through send and receive socket buffers, and in fact waits for bytes to get stored in the output file. There is no need to implement out-of-band acknowledgements and there's also no need for the client to wait as suggested in section II.A https://linuxnetworkstack.files.wordpress.com/2013/03/paper.pdf in case file content is mutable.

"wait an “appropriate” amount of time before rewriting the same portion of file"

UPDATE 3:

A modified example incorporating fixes by @EJP and @the8472, with both length and file checksum verification, without output tracing. Note that computing CRC32 checksum for a large file may take a few seconds to complete.

Client:

Server:

0 投票
2 回答
1234 浏览

java - Netty 中是否有类似 transferFrom 的零拷贝功能?

我正在开发一个处理相当大的有效载荷的 Http 服务器。由于Netty提供了零拷贝,所以我想到了使用Netty的零拷贝对payload进行零拷贝。但似乎 Netty 只提供transferTo(WritableByteChannel target, long position) 但不提供transferFrom()直接将内容读入文件的类似方法。

是这样还是有任何解决方法?谢谢。

0 投票
1 回答
111 浏览

c# - 反应式扩展,包装第三方 API 事件 - 零拷贝?

我有一个我没有来源的第三方 API。我实例化一个回调到这样的事件:

如何将其包装到 Rx Observable.FromEvent 中?

另外,有没有办法让包装副本的开销尽可能少(零副本)?

0 投票
2 回答
856 浏览

linux - 带礼物和不带礼物的 vmsplice(2) 的语义是什么?

我正在尝试了解系统调用的功能(此处vmsplice(2)的手册页)。关于标志的效果,我有两个问题:SPLICE_F_GIFT

  1. 手册页说,一旦将页面赠送给内核,就不能再修改内存。这是否意味着内存被永久固定,或者它可能指的是可以通过赠送过程取消映射的虚拟内存,而不是物理内存?换句话说,这个的典型用法是什么样的?

  2. 如果我不设置SPLICE_F_GIFTvmsplice(2)与矢量化写入系统调用有什么不同writev(2)吗?

0 投票
0 回答
115 浏览

linux - 拼接后源文件发生变化时,splice(2)的语义是什么?

我试图弄清楚splice(2)(man page here)的语义。

假设我在磁盘上有一个常规文件,我想将其当前内容的一部分写入管道(实际上是/dev/fuse在具有该FUSE_SPLICE_WRITE功能的系统上)。我认为这看起来像:

手册页是这样说的:

尽管我们谈论复制,但通常会避免实际复制。内核通过将管道缓冲区实现为一组指向内核内存页面的引用计数指针来实现这一点。内核通过创建引用页面的新指针(用于输出缓冲区)并增加页面的引用计数来在缓冲区中创建页面的“副本”:只复制指针,而不复制缓冲区的页面。

这让我担心如果文件内容随后在感兴趣的范围内发生变化会发生什么。管道中的数据是否继续反映文件以前的内容?(如果是这样,它是如何实现的?)

如果SPLICE_F_MOVE设置了,这些会改变吗?我意识到这个标志在现代内核上被忽略了,但我在谈论预期的语义,因为手册页声称它可能有一天会恢复。

0 投票
1 回答
239 浏览

java - 在单个上下文切换中将相同的 tcp 消息发送到多个目标/主机

我需要通过 tcpip 套接字有效地将相同的消息发送/扇出到主机列表。该逻辑将需要遍历每个套接字以将消息写出。如果这个逻辑运行在 linux 用户模式下,底层 OS 调用系统调用的次数会和主机的数量一样多。这是昂贵的,因为每个系统调用都需要用户模式到内核模式的上下文切换。

如果可以在采用主机列表(文件描述符)的系统调用中移动循环,则效率会更高。linux中是否存在这样的系统调用?

如果存在这样的系统调用,我们在 Java 中是否有等效的 API(类似于 Java 中的 transferTo() 对应于 linux 中的 sendfile())?

0 投票
1 回答
1236 浏览

linux - 如何在 POSIX 中实现零拷贝机制?

我想在本地/网络的两个进程之间共享/传输数据。通用 IPC 机制共享内存和消息队列可用于传输数据。但这些机制涉及多个副本。

我遇到了零复制机制,它减少了 CPU 的复制开销。Linux 使用sendfile和支持这一点splice。这些 API 不在 POSIX 中。如何仅使用 POSIX API 实现零拷贝?

0 投票
0 回答
1882 浏览

java - Java 中的 SendFile 和 transferTo

我正在使用 CentOs 内核版本 2.6.32。我计划使用 NIO 进行有无 transferTo(sendFile) 的测试。我的测试是将一个 1GB 的文件从一个目录复制到另一个目录。但是,由于使用 transferTo(),我没有发现任何显着的性能改进。请让我知道文件到文件 sendFile 是否真的在 Linux 内核中有效,或者只有文件到套接字才有效?我需要为 sendFile 启用任何东西吗?

示例代码:

0 投票
3 回答
160 浏览

java - 如何引用数组的一部分?

给定一个对象byte[],当我们想要对这样的对象进行操作时,我们通常需要它的一部分。在我的特定示例中,我byte[]从线中获取,其中前 4 个字节描述消息的长度,然后是另外 4 个字节的消息类型(映射到具体 protobuf 类的整数),然后剩余byte[]的是消息的实际内容......像这样

为了解析此消息,我必须将内容部分传递给知道如何从中解析实例的特定类...问题是通常没有提供任何方法,因此您可以指定解析器从何处读取大批...

所以我们最终要做的是复制该数组的剩余 chuks,这是无效的......

据我所知,在java中不可能创建另一个byte[]引用,它实际上引用了一些byte[]只有2个索引的原始更大数组(这是导致内存泄漏的String方法)......

我想知道我们如何解决这样的情况?我想放弃protobuf只是因为它没有提供一些parseFrom(byte[], int, int)没有意义...... protobuf只是一个例子,任何东西都可能缺少那个api......

那么这是否会迫使我们编写低效的代码,或者有什么可以做的呢?(除了添加该方法)...

0 投票
1 回答
425 浏览

java - 带有 HttpServletResponse 的零复制 byte[] 或 ByteBuffer

使用 Google 的 FlatBuffer 时,最终使用的类型是 a ByteBuffer(可以只包装 a byte[])。我将它与HttpServletResponse. 问题变成了 ServletsPrintWriter不提供byte[]ByteBuffer编写。

HttpServletResponse无需将ByteBuffer/复制byte[]到另一种类型即可从 an 输出的任何提示?