Я пытаюсь отправить массив байтов, содержащий 16 элементов поверх сокетов, используя DataOutputStream на клиенте и DataInputStream на сервере.
Это методы, которые я использую для отправки/получения.
public void sendBytes(byte[] myByteArray) throws IOException {
sendBytes(myByteArray, 0, myByteArray.length);
}
public void sendBytes(byte[] myByteArray, int start, int len) throws IOException {
if (len < 0)
throw new IllegalArgumentException("Negative length not allowed");
if (start < 0 || start >= myByteArray.length)
throw new IndexOutOfBoundsException("Out of bounds: " + start);
dOutput.writeInt(len);
if (len > 0) {
dOutput.write(myByteArray, start, len);
dOutput.flush();
}
}
public byte[] readBytes() throws IOException {
int len = dInput.readInt();
System.out.println("Byte array length: " + len); //prints '16'
byte[] data = new byte[len];
if (len > 0) {
dInput.readFully(data);
}
return data;
}
Все работает отлично, и я могу напечатать длину массива байтов, массив байтов (зашифрованный текст), а затем расшифровать массив байтов и распечатать исходный текст, который я отправил, но сразу же после его печати в консоли программа вылетает с помощью OutOfMemoryError: Java heap space
.
Я читал это, как правило, из-за того, что не смывал DataOutputStream, но я вызываю его внутри метода sendBytes, поэтому он должен очищать его после отправки каждого массива.
Компилятор сообщает мне, что ошибка происходит внутри readBytes в строке byte[] data = new byte[len];
а также где я вызываю readBytes()
в основном методе.
Любая помощь будет оценена!
редактировать
Я действительно получаю неожиданные результаты.
17:50:14 Server waiting for Clients on port 1500. Thread trying to create Object Input/Output Streams 17:50:16 Client[0.7757499147242042] just connected. 17:50:16 Server waiting for Clients on port 1500. Byte array length: 16 Server recieved ciphertext: 27 10 -49 -83 127 127 84 -81 48 -85 -57 -38 -13 -126 -88 6 Server decrypted ciphertext to: asd 17:50:19 Client[0.7757499147242042] Byte array length: 1946157921
Я readBytes()
в цикле while, поэтому сервер будет прослушивать что-либо, передаваемое через сокет. Я предполагаю, что он пытается запустить его во второй раз, даже если ничего не было отправлено, а переменная len
каким-то образом установлена на 1946157921. Какая логика могла бы быть за этим?
Вы должны отправить что-то еще через сокет; не читая его так же, как вы его написали; и поэтому выходить из синхронизации. Эффект будет заключаться в том, что вы читаете длину, которая не является реальной длиной; слишком большой; и заканчивается память, когда вы пытаетесь выделить его. Ошибка в этом коде отсутствует. За исключением, конечно, что если len == 0, вы не должны выделять массив bye при чтении.
Я прочитал это, как правило, из-за того, что не смыл DataOutputStream
Это не так.
Переменная len как-то устанавливается на 1946157921.
Точно так же, как и было предсказано. QED
У вас закончилась доступная куча. Быстрое решение для этого будет увеличивать (или указывать отсутствующий) параметр -Xmx в ваших параметрах запуска JVM до уровня, на котором приложение может выполнить задачу под рукой.
Запустите приложение с помощью -Xms1500m в консоли, в Netbeans его можно найти в проекте properties-> Run-> VM.
Сегодня я столкнулся с этой проблемой, связанной с памятью, и после настройки с Xms я смог исправить эту проблему. Проверьте, работает ли он с вами, если есть что-то действительно большее, чем вам нужно будет проверить, как вы можете улучшить свой код.
Xmx
который увеличивает максимальное пространство кучи.
len
слишком велик для доступной памяти. Попробуйте вывести его, прежде чем выделять байтовый массив, чтобы увидеть, сколько байтов вы запрашиваете.