Как вы сказали, легко достижимые объекты собираются, когда существует нехватка памяти, и один из способов обеспечить это - создать фактическое давление памяти.
Например, следующий код
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();
Когда мягкая ссылка была единственной ссылкой на объект, очистка ее делает объект также пригодным для обычной сборки мусора, независимо отфактическое давление памяти.