Java все еще использует системную память после освобождения объектов и сборки мусора - PullRequest
9 голосов
/ 27 ноября 2008

Я использую JVM 1.5.0 (Mac OS X по умолчанию) и отслеживаю свою программу Java в Activity Monitor. У меня есть следующее:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;

public class MemoryTest {

public static void memoryUsage() {
 System.out.println(
     Runtime.getRuntime().totalMemory() - 
     Runtime.getRuntime().freeMemory()
 );
}

public static void main( String[] args ) throws IOException {

    /* create a list */
    ArrayList<Date> list = new ArrayList<Date>();

    /* fill it with lots of data */
    for ( int i = 0; i < 5000000; i++ ) {
        list.add( new Date() );
    } // systems shows ~164 MB of physical being used

    /* clear it */
    memoryUsage();      //  about 154 MB
    list.clear();
    list = null;
    System.gc();
    memoryUsage();      //  about 151 KB, garbage collector worked

    // system still shows 164 MB of physical being used.
    System.out.println("Press enter to end...");
    BufferedReader br = new BufferedReader( 
            new InputStreamReader( System.in )
            );
    br.readLine();
}

}

Так почему же физическая память не освобождается, хотя сборщик мусора работает нормально?

Ответы [ 4 ]

19 голосов
/ 27 ноября 2008

Многие JVM никогда не возвращают память операционной системе. Делает это так или нет, зависит от реализации. Для тех, кто этого не делает, ограничения памяти, указанные при запуске, обычно через флаг -Xmx, являются основным средством резервирования памяти для других приложений.

Мне трудно найти документацию по этому вопросу, но документация для сборщика мусора для Sun 5 от Sun решает эту проблему, предполагая, что при правильных условиях куча будет уменьшаться, если правильный сборщик по умолчанию используется & mdash; если более 70% кучи свободны, она будет уменьшаться, и только 40% будет свободной. Параметры командной строки для управления ими -XX:MinHeapFreeRatio и -XX:MaxHeapFreeRatio.

5 голосов
/ 27 ноября 2008

Существует несколько параметров командной строки для JVM, которые помогают настроить размер кучи, используемой Java. Все знают (или должны знать) о -Xms и -Xmx, которые устанавливают минимальный и максимальный размер кучи.

Но есть также -XX: MinHeapFreeRatio и -XX: MaxHeapFreeRatio, которые являются соответствующими пределами, между которыми JVM управляет свободным пространством. Это достигается за счет сокращения используемой кучи и может снизить потребление памяти программой.

Вы можете найти больше информации здесь:

3 голосов
/ 27 ноября 2008

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

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

0 голосов
/ 27 ноября 2008

Может ли ОС показывать память, которая в данный момент выделена для программы? Даже если выделено 150 ~ МБ, это не означает, что используется 150 ~ МБ.

...