Efficient data transfer through zero copy.
Суть: при копировании File -> Socket через transferTo удается избежать лишних копирований данных и переключений user mode <-> kernel mode. Остается два копирования, но они делаются не через CPU, а через DMA.
Вопрос: возможно ли достичь аналогичного эффекта при копировании Socket -> Socket? Пока ищу ответ. Скажем, если я использую ByteBuffer.allocateDirect(...).
Суть: при копировании File -> Socket через transferTo удается избежать лишних копирований данных и переключений user mode <-> kernel mode. Остается два копирования, но они делаются не через CPU, а через DMA.
Вопрос: возможно ли достичь аналогичного эффекта при копировании Socket -> Socket? Пока ищу ответ. Скажем, если я использую ByteBuffer.allocateDirect(...).
Возможно. Но требуются Линукс-специфический вызов: http://linux.die.net/man/2/splice
ОтветитьУдалитьСобственно, transferTo использует полустандартный sendfile, который в Линуксе реализован через splice.
Подключить этот вызов можно руками через JNA. Кстати, sendfile тоже может вроде бы между сокетами работать.
Спасибо за информацию. Видимо, надо брать сорцы Sun/Oracle HotSpot JVM под Linux и копать там.
ОтветитьУдалитьКонтекст такой - допустим мы делаем SOCKS4/5 proxy на Java. И допустим, что малую долю трафика (скажем HTTP на vkontakte.ru) мы хотим вытягивать в java и работать с ними: парсить, анализировать, хранить, делать выборки по сохраненному. Остальную же часть (большую) мы просто ходим перекидывать между сокетами средствами Linux == не платить за использование java. Вопрос: ByteBuffer.allocateDirect(...) - позволит это сделать?
И, Да - задача в "ментовском"/ФСБ/СБУ стиле. Нет, на них не работаю, просто интересно:)
ОтветитьУдалитьДа, ByteBuffer позволит это сделать. Вам просто надо обернуть splice() из libc и вызывать его для bytebuffer'а. Это в пару строк кода с помощью JNA можно сделать.
ОтветитьУдалить