Java 6 чрезмерное использование памяти

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

var array = [UInt8](count: a.count, repeatedValue: 0x00)

или вы можете использовать метод добавления массива в своем цикле.

for var i:Int = 0; i < a.count; i++
{
   array.append( UInt8(a[i]^b[i]) )
}
22
задан 12 revs, 2 users 100% 22 January 2009 в 00:50
поделиться

6 ответов

За последние несколько недель у меня была причина исследовать и исправить проблему с объектом объединения потока (предварительный Java 6 многопоточных пулов выполнения), где, запускал намного больше потоков, чем необходимый. В рассматриваемых заданиях могло быть до 200 ненужных потоков. И потоки постоянно умирали и новые, заменяющие их.

исправлявший ту проблему, я думавший запустить тест снова, и теперь кажется, что потребление памяти стабильно (хотя на приблизительно 20 МБ выше, чем с более старым JVMs).

, Таким образом, мое заключение состоит в том, что скачки в памяти были связаны с количеством потоков, работающих (несколько сотен). К сожалению, у меня нет времени для экспериментирования.

, Если кто-то хотел бы экспериментировать и ответить на это с их заключениями, я приму тот ответ; иначе я приму этого (после 2-дневного времени ожидания).

кроме того, уровень отсутствия страницы является путем вниз (фактором 10).

кроме того, меры к пулу потоков исправили некоторые состязательные проблемы.

3
ответ дан 3 revs 29 November 2019 в 04:57
поделиться

В ответ на обсуждение в комментариях к ответу Ran вот тестовый сценарий, который доказывает, что JVM будет память выпуска назад к ОС при определенных обстоятельствах:

public class FreeTest
{
    public static void main(String[] args) throws Exception
    {
        byte[][] blob = new byte[60][1024*1024];
        for(int i=0; i<blob.length; i++)
        {
            Thread.sleep(500);
            System.out.println("freeing block "+i);
            blob[i] = null;
            System.gc();
        }
    }
}

я вижу, что размер процесса JVM уменьшается, когда количество достигает приблизительно 40, и на Java 1.4 и на Java 6 JVMs (от Sun).

можно даже настроить точное поведение с -XX:MaxHeapFreeRatio и-XX:MinHeapFreeRatio опции - некоторые опции на той странице могут также помочь с ответом на исходный вопрос.

13
ответ дан Michael Borgwardt 29 November 2019 в 04:57
поделиться

Я не знаю об отсутствиях страницы. но об огромной памяти выделил для Java:

  1. JVM Sun <забастовка> только выделяет память, никогда не освобождает, это (до смерти JVM) освобождает память только после определенного отношения между потребностями внутренней памяти и выделенными отбрасываниями памяти под (настраиваемым) значением. JVM запускается с суммы, определенной в-Xms, и может быть расширена до суммы, определенной в-Xmx. Я не уверен, каковы значения по умолчанию. Каждый раз, когда JVM нужно больше памяти (новые объекты / примитивы / массивы), это выделяет весь блок от ОС. Однако то, когда потребность спадает (мгновенная потребность, см. 2 также), она не делает, освобождает память, поддерживают ОС сразу , но сохраняет его к себе, пока то отношение не было достигнуто. Мне когда-то сказали, что JRockit ведет себя лучше, но я не могу проверить его.

  2. JVM Sun выполняет полный GC на основе нескольких триггеров. Один из них является суммой доступной памяти - когда это падает слишком много, JVM пытается выполнить полный GC для освобождения еще немного. Так, когда больше памяти выделяется от ОС (мгновенная потребность), шанс для полного GC понижен. Это означает, что, в то время как можно видеть 30 МБ "живых" объектов, могло бы быть намного больше "мертвых" объектов (не достижимо), просто ожидая GC для случая. Я знаю, что yourkit имеет прекрасный вид, названный "мертвые объекты", где можно видеть эти "остатки".

  3. В "-сервер" режим, JVM Sun выполняет GC в параллельном режиме (как отклонено более старая последовательная "остановка мировой" GC). Это означает, что, в то время как может быть мусор для сбора, он не мог бы быть сразу собран из-за других потоков, занимающих все доступное процессорное время. Это будет собрано прежде, чем достигнуть из памяти (хорошо, отчасти. см. http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html ), если больше памяти может быть выделено от ОС, это могло бы быть перед выполнениями GC.

Объединенный, большая начальная конфигурация памяти и кратковременные вспышки, создающие много недолгих объектов, могли бы создать сценарий, как описано.

редактирование: измененный "никогда deallcoates" к "только после достигнутого отношения".

9
ответ дан Ran Biron 29 November 2019 в 04:57
поделиться

Чрезмерное создание потока объясняет Вашу проблему отлично:

, Если у Вас когда-нибудь действительно должны быть сотни потоков aound, размер стопки потока может быть настроен через-Xss параметр командной строки.

7
ответ дан Michael Borgwardt 29 November 2019 в 04:57
поделиться

Сборка "мусора" является довольно тайной наукой. Поскольку состояние разрабатывает, ненастроенное поведение изменится в ответ.

Java 6 имеет различное поведение GC по умолчанию и различную "эргономику" к более ранним версиям JVM. Если Вы скажете ему, что это может использовать больше памяти (или явно на командной строке, или неявно путем отказа определить что-либо более явное), это будет использовать больше памяти, если это будет полагать, что это, вероятно, улучшит производительность.

В этом случае, Java 6, кажется, полагает, что резервирование дополнительного пространства, в которое могла превратиться "куча", даст ему лучшую производительность - по-видимому, потому что это полагает, что это вызовет больше объектов умереть в пространстве Eden и ограничит количество объектов, продвинутых на штатное пространство поколения. И от спецификаций Ваших аппаратных средств, JVM не думает, что это дополнительное зарезервированное пространство "кучи" вызовет любые проблемы. Обратите внимание, что многие (хотя не все) предположений JVM делают в том, чтобы сделать ее вывод, основаны на "типичных" приложениях, а не Вашем определенном приложении. Это также делает предположения на основе Ваших аппаратных средств и профиля ОС.

, Если JVM сделала неправильные предположения, можно влиять на ее поведение через командную строку, хотя легко понять вещи превратно...

информация об изменениях производительности в java 6 может быть найдена здесь .

существует дискуссия о последствиях управления памятью и производительности в Техническое описание управления памятью .

4
ответ дан Bill Michell 29 November 2019 в 04:57
поделиться

Вы используете коллектор ConcMarkSweep? Это может увеличить объем памяти, требуемый для Вашего приложения из-за увеличенной фрагментации памяти, и "плавающий мусор" - возражает, что становятся недостижимыми только после того, как коллектор исследовал их, и поэтому не собран до следующей передачи.

0
ответ дан sk. 29 November 2019 в 04:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: