Когда «Ссылочный объект» может быть восстановлен? - PullRequest
1 голос
/ 14 сентября 2011

Теперь я встретил странный случай, например:

public class SoftRefDemo {

     private static List<SoftReference<String>> cache;

     public static void main(String[] args) {
         int total = 3000000;
         cache = new ArrayList<SoftReference<String>>(total);
         for (int i = 0; i < total; i++) {
             cache.add(new SoftReference<String>("fafsfsfsdf" + i));
         }

         System.out.println(cache.size());
     }

}

Я установил настройку JVM: -Xms20m -Xmx40m.Когда я хочу поместить многие из SoftReference в кэш, JVM завершает работу без каких-либо подсказок или исключений.На самом деле, я сомневаюсь в действии SoftReference, это специальный объект для JVM.Может кто-нибудь объяснить, что происходит с этой программой?

Еще два вопроса: 1. Есть ли дополнительный метод выделения памяти для этих «специальных эталонных экземпляров» в куче JVM?2. Когда эти ссылочные экземпляры могут быть освобождены, когда экземпляр, на который они указывают, был освобожден?Большое спасибо!

Ответы [ 2 ]

1 голос
/ 21 сентября 2011

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

Каждый экземпляр SoftReference занимает 24 байта кучи-памяти сам по себе (это верно для 32-битной Sun JVM и может отличаться для других виртуальных машин).Вы пытаетесь сохранить в списке 3 000 000 экземпляров, что означает, что вам понадобится как минимум ~ 70 МБ пространства кучи только для хранения SoftReference объектов.

SoftReference объект хранит «мягкую ссылку» на объект с мягкой доступностью (в вашем случае String), а спецификация JVM гарантирует, что эти ссылки будут очищены (т. Е. Объекты String будут собираться мусором) перед виртуальной машинойбросает OutOfMemoryError.Однако JVM будет НЕ собирать мусор объектами SoftReference, поскольку вы сохраняете сильные ссылки на них из списка cache.(Так что если вам нужно удалить объект SoftReference из кучи - удалите его из списка cache).

0 голосов
/ 14 сентября 2011

Если я запускаю эту программу с -mx40m

char[] chars = new char[4096];
List<SoftReference<String>> strings = new ArrayList<SoftReference<String>>();
do {
  strings.add(new SoftReference<String>(new String(chars)));
} while(strings.get(0).get()!=null);
int nulls=0, set=0;
for (SoftReference<String> string : strings) {
  if(string.get() == null) nulls++; else set++;
}
System.out.println("nulls= "+nulls+", was still set= "+set);

, я получаю

nulls= 4618, was still set= 1

Одна из проблем, связанных с WeakReferences и SoftReferences, заключается в том, что они, как правило, удаляются сразу..


Попробуйте WeakReference, SoftReferences понятны, только если это действительно необходимо.Чтобы сделать их более понятными, попробуйте создать достаточно большой массив, чтобы вызвать ошибку OutOfMemoryError.

  1. Все объекты находятся в куче.Даже статические поля обернуты в псевдообъект, который находится в куче.(Это более позднее поведение не определено, но, как я видел, оно работает)

  2. Ссылочный экземпляр освобождается после того, как он был удален (как и любой другой объект)

...