Ошибка OutOfMemory в toString при кодировании ISO-8859-1 в SuSE Linux - PullRequest
0 голосов
/ 10 июня 2011

Я долго бился над этим вопросом. Я беру строку в коде 27K (аналогичную кодировке URL) и превращаю ее обратно в строку открытого текста 9K "ISO-8859-1".

byte outarray[] = new byte[decoded_msg_length]; // 9K
byte inarray[];
try {
  inarray = instring.getBytes("ISO-8859-1"); // eg: "ÀÀÀÚßÐÀÀÃÐéÙÓåäàÈÂÁÙÈ...."
  inarray = null; // free up whatever memory possible.
  // ... for loop decodes chunks of 4 bytes...

  Runtime runtime = Runtime.getRuntime();
  System.out.println("freeMemory1="+runtime.freeMemory()); // freeMemory1=86441120
  // yes I've tried methods like new String( outarray, "ISO-8859-1" );, etc.
  ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
  byteStream.write(outarray);
  outarray=null;
  runtime.gc();

  System.out.println("freeMemory2="+runtime.freeMemory()); //freeMemory2=133761568
  // return new String(outarray,"ISO-8859-1"); // OutOfMemoryException thrown here
  // return new String(outarray); // OutOfMemoryException thrown here too
  return byteStream.toString("ISO-8859-1"); // OutOfMemoryException thrown here also
  // sample output: "JOHN H SMITH  123 OAK ST..."
} catch( IOException ioe ) {
  ...
}
// Thrown exception:
Exception in thread "main" java.lang.OutOfMemoryError
    at java.lang.StringCoding.decode(StringCoding.java:510)
    at java.lang.String.<init>(String.java:232)
    at java.io.ByteArrayOutputStream.toString(ByteArrayOutputStream.java:195)
    ...

Похоже, у меня много памяти. Этот же код прекрасно работает, если в Windows менее половины свободной памяти. Я использую это как отдельный отдельный класс. Кто-нибудь знает какие-либо проблемы кодирования Linux с утечкой памяти JRE?

$ java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pxi32dev-20080315 (SR7))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20080315 (JIT enabled)
J9VM - 20080314_17962_lHdSMr
JIT  - 20080130_0718ifx2_r8
GC   - 200802_08)
JCL  - 20080314

Ответы [ 2 ]

1 голос
/ 12 июня 2011

Я нашел решение, хотя я не уверен, точная причина, по которой это происходит - скорее всего, какая-то внутренняя статическая буферная переменная.Несмотря на то, что ошибка выдает ошибку toString, исправление состояло в том, чтобы изменить размер decoded_msg_length так, чтобы он совпадал с instring.

По какой-то причине мне еще предстоит разобраться, наборы instring.getBytes ("ISO-8859-1")размер некоторого внутреннего буфера, заполненного byteStream.toString ("ISO-8859-1").Если установить значение decoded_msg_length на один байт меньше этой длины, Java выдаст ошибку, даже если нет ничего небезопасного, и я работаю с двумя разными переменными.

Чтобы завершить это, я могу использовать CharsetDecoder ивсе равно не получится.Я объясню это ошибкой ОС JVM.Без этого причудливого исправления код отлично работает в других ОС и JVM.

1 голос
/ 10 июня 2011

Размер кучи Java может иметь другое ограничение по умолчанию в вашей среде Linux по сравнению с Windows.Вы можете проверить это с помощью метода Runtime.maxMemory ().http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html#maxMemory()

Если в Linux ограничение меньше, вы можете увеличить его с помощью аргумента командной строки -Jmx для java,

java -Xmx1024m YourClassNameHere

1024m увеличит размер кучи до1 ГБ, вы можете настроить количество по мере необходимости.Это максимальная сумма, ваша программа может использовать гораздо меньше.

...