Java: за счет вызова Runtime.freeMemory (), Runtime.totalMemory () и Runtime.maxMemory () - PullRequest
9 голосов
/ 15 декабря 2011

У меня есть Map в памяти, в которой хранятся мои объекты. Я хотел бы очистить память, когда у меня заканчивается память. Я делаю это прямо сейчас:

void add(K key, V value) {
    if (underPressure()) {
        flush(innerMap);
    }
    innerMap.add(k, v);
}

boolean underPressure() {
    Runtime rt = Runtime.getRuntime();
    long maxMemory = rt.maxMemory();
    long freeMemory = rt.freeMemory();

    return (double) freeMemory / maxMemory < threshold;
}

Как underPressure() вызывается на каждой вставке, насколько это дорого? Насколько я понимаю, это приблизительно, оно должно быть каким-то образом кэшировано jvm, но кто-нибудь знает об этом больше по-настоящему?

Ответы [ 3 ]

5 голосов
/ 01 марта 2014

Начиная с Java 7 больше нет необходимости опрашивать свободную память.Можно зарегистрироваться на событие сбора мусора.Смотрите этот пост: http://www.fasterj.com/articles/gcnotifs.shtml

Так что лучший способ, о котором я могу подумать, это проверить свободную память после сборки мусора, а затем освободить дополнительное место, если это необходимо.

3 голосов
/ 17 декабря 2011

Почему бы не использовать JMXBeans для этого.Он был разработан для упрощения операций такого типа ..

Из документов ...

API предоставляет доступ к такой информации, как:

Number of classes loaded and threads running
Virtual machine uptime, system properties, and JVM input arguments
Thread state, thread contention statistics, and stack trace of live threads
Memory consumption
Garbage collection statistics
Low memory detection
On-demand deadlock detection
Operating system information

В частности, см. Пример кода в MemoryPoolMXBean

2 голосов
/ 15 декабря 2011

Непосредственно не отвечая на ваш вопрос, но, как уже сказано в комментариях freeMemory считает свободную память, а не память, которая будет доступна после GC, таким образом, если вы вызываете freeMemory просто перед запуском GC вы можете подумать, что достигли своего предела «пониженного давления», но у вас также может быть достаточно свободной памяти после следующего запуска GC.

Другой подход может заключаться в создании легко достижимого объекта и проверке, был ли он заявлен ГК:

что-то вроде:

SoftReference<Object> sr = new SoftReference<Object>(new Object(),new ReferenceQueue<Object>());
public boolean underPressure(){
    if (sr.isEnqueued()) {
        // recreate object to monitor
        sr = new SoftReference<Object>(new Object(),new ReferenceQueue<Object>());
        return true;
    }
    return false;
}
...