Как я могу заставить релиз мягкую ссылку - PullRequest
0 голосов
/ 14 февраля 2019

Я знаю выпуск мягкой ссылки только тогда, когда у меня нет памяти, но могу ли я сделать это вручную?

Мой код:

  Object object = new Object();
  ReferenceQueue queue = new ReferenceQueue();
  SoftReference softReference= new SoftReference(object, queue);
  object = null;
  System.gc();
  //now I force release soft reference.

Я хочу получить релиз softReference,

можно ли это сделать?

Есть ли решение в последних версиях Java (8-11)?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019
  • System.gc() может никогда не запускаться в зависимости от порога, установленного до начала сбора мусора.
  • Один из вариантов - настроить параметр -XX:SoftRefLRUPolicyMSPerMB=2500 в конфигурации JVM.Это означает, что любой элемент с мягкой ссылкой будет удален через 2,5 секунды.Надеюсь, это поможет.
0 голосов
/ 14 февраля 2019

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

Например, следующий код

Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
new Thread(() -> {
    try {
        queue.remove();
        System.out.println("collected");
    } catch (InterruptedException ex) {}
}).start();
object = null;
try {
    object = new int[10][10][10][10][10][10][10][10][10][10][10][10];
} catch(OutOfMemoryError err) {
    System.out.println("...");
}

печатает

collected
...

на моей машине.

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

Многомерный массивВыделение, которое является массивом массивов в Java, кажется, достаточно запутывает текущую реализацию, поэтому она действительно пытается.Альтернативный подход, использующий простые массивы, состоит в том, чтобы размещать в цикле, начиная с небольшого размера, и увеличивать его до сбоя.

Существует риск того, что оптимизатор JVM обнаружит, что выделенный объект никогда не используется, и устранитОднако при полном распределении это редко случается с кодом, который выполняется только один раз.

Если единственным желаемым эффектом является очистка и постановка в очередь SoftReference, например, для проверки кода обработки, вы можете просто вызватьclear(), за которым следует enqueue() для ссылочного объекта.

Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
new Thread(() -> {
    try { queue.remove(); } catch (InterruptedException ex) {}
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softReference= new SoftReference(object, queue);
new Thread(() -> {
    try {
        queue.remove();
        System.out.println("collected");
    } catch (InterruptedException ex) {}
}).start();
object = null;

Thread.sleep(500);
softReference.clear();
softReference.enqueue();

Когда мягкая ссылка была единственной ссылкой на объект, очистка ее делает объект также пригодным для обычной сборки мусора, независимо отфактическое давление памяти.

0 голосов
/ 14 февраля 2019
  1. Как правило, вы не можете: System.gc(); только посоветовать JVM запустить GC

  2. only when I have no memory - это совершенно неправильно.GC работает немного сложнее, и есть множество настроек для GC на уровне JVM ...

...