Java still uses system memory after deallocation o

2020-01-25 09:43发布

I am running JVM 1.5.0 (Mac OS X Default), and I am monitoring my Java program in the Activity Monitor. I have the following:

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();
}

}

So why doesn't the physical memory get freed even though the garbage collector seems to work just fine?

4条回答
啃猪蹄的小仙女
2楼-- · 2020-01-25 09:45

You need to use a JVM-specific profiler to monitor the actual heap space being used by the program as opposed to memory allocated to the JVM.

The JVM is not only reluctant to release heap memory that it allocated, but tends to gobble up space for different reasons, including just-in-time compilation.

查看更多
三岁会撩人
3楼-- · 2020-01-25 10:00

Is the OS perhaps showing the memory which is currently allocated to the program - Even though 150~ MB is allocated it does not mean 150~ MB is in use.

查看更多
混吃等死
4楼-- · 2020-01-25 10:10

Many JVMs never return memory to the operating system. Whether it does so or not is implementation-specific. For those that don't, the memory limits specified at startup, usually through the -Xmx flag, are the primary means to reserve memory for other applications.

I am having a hard time finding documentation on this subject, but the garbage collector documentation for Sun's Java 5 does address this, suggesting that under the right conditions, the heap will shrink if the correct collector is used—by default, if more that 70% of the heap is free, it will shrink so that only 40% is free. The command line options to control these are -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio.

查看更多
趁早两清
5楼-- · 2020-01-25 10:10

There are several command line options for the JVM which help to tune the size of the heap used by Java. Everybody knows (or should know) about -Xms and -Xmx, which set the minimum and the maximum size of the heap.

But there is also -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio which are the respective limits between which the JVM manages free space. It does this by shrinking the used heap, and it can lower the memory consumption of the program.

You can find more information here:

查看更多
登录 后发表回答