2014-01-29 7 views
1

http://www.coderpanda.com/java-socket-programming-transferring-large-sized-files-through-socket/из памяти размера Java кучи

Код в приведенной выше ссылке, но работает Шифрование до определенного количества данных могут быть переданы. когда я пытался передать фильм формата .mkv размером около 334 МБ, он дает мне ошибку «из памяти, размер кучи java». Я ничья, и я не знаю, как это решить. Я попытался увеличить буферизацию в клиентской программе, но проблема все еще сохраняется. пожалуйста помогите.

+1

Попробуйте ** уменьшить ** размер буфера или увеличить кучу JVM. –

+2

Я не могу не заметить, что код слишком сложный для того, что он делает. Нет необходимости копировать прочитанные буферы, а фоновый поток также бесполезен. Вместо этого сервер должен запустить один фон для каждого подключения. –

+0

Перенос больших файлов должен выполняться путем приобретения [* канала * для сокета] (http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#getChannel()) и [канал для файла] (http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#open (java.nio.file.Path,% 20java.nio .file.OpenOption ...)) вместо потоков и вызов ['targetFileChannel.transferFrom (sourceSocketChannel, 0, Long.MAX_VALUE)'] (http://docs.oracle.com/javase/7/docs/api /java/nio/channels/FileChannel.html#transferFrom(java.nio.channels.ReadableByteChannel,%20long,%20long)) для всей передачи. – Holger

ответ

0

Вам нужно взглянуть на параметры памяти JVM. Вам нужно увеличить размер кучи JVM, а не размер буфера. проверить это параметры

-Xmx2048m -> this param to set the max memory that the JVM can allocate 
-Xms1024m -> the init memory that JVM will allocate on the start up 
-XX:MaxPermSize=512M -> this for the max Permanent Generation memory 
-XX:MaxNewSize= -> this need to be 40% from your Xmx value 
-XX:NewSize=614m -> this need to be 40% from your Xmx value 
6

Проблема эта линия:

byte[] readBuffer = new byte[1024 * 100000]; 

Это выделяет буфер ~ 100 мегабайта ... который до смешного велик.

Либо уменьшите его (в 10 или 100 раз), либо запустите приложение с большей кучей.

(@Aaron Digulla и @ комментарии Holger в выше, также кстати. Это на самом деле не то, что можно было бы назвать «высокое качество» код ...)

+0

Спасибо Stephen :) – user3247825

+1

+1, но я бы уменьшил его примерно в 10 000. Учитывая, что в ядре также есть буфер отправки сокета, преимущества буферизации приложения асимптотически равны нулю, когда вы выходите за пределы небольшого числа K. – EJP

0

попробуйте использовать JDK 5.0 или выше. в jdk 4.0 начальный размер кучи был 64 МБ. JDK 7.0 u9 или выше будет намного лучше.

0

Большая часть кода в этой ссылке является полным мусором. Нет необходимости использовать огромные буферы, и, конечно, нет необходимости использовать System.arraycopy() при копировании потоков. Любой разумный размер буфера будет делать. Это не будет сотни мегабайт, это будет измерено в килобайтах.

канонический способ скопировать поток в Java выглядит следующим образом:

while ((count = in.read(buffer)) > 0) 
{ 
    out.write(buffer, 0, count); 
} 

Это работает для любого размера буфера больше нуля. Обратите внимание, что нет никакой System.arraycopy() и не выделяет новые байтовые массивы во время копирования, поэтому у него не может быть нехватка памяти. Заметьте также, что это значительно проще кода в вашей ссылке.

Ваш вопрос отмечен NIO, но код в ссылке использует потоки, поэтому я дал вам ответ на поток.

+0

OK спасибо, сэр. И сэр, было бы замечательно, если бы вы дали мне ссылку, чтобы узнать о передаче NIO. – user3247825

+0

Я не вижу причин беспокоиться о NIO для этой простой задачи. – EJP

Смежные вопросы