Руководство Java PhantomReference
1. PhantomReference
В этой статье мы обсудим класс PhantomReference. Перед началом работы я рекомендую вам ознакомиться с классами WeakReference и SoftReference. Все эти три класса имеют одни и те же основные характеристики и не нуждаются в повторном упоминании.
PhantomReference Constructors
PhantomReference(T innerObject, ReferenceQueue<? super T> queue)
PhantomReference имеет только один constructor. Чтобы создать объект PhantomReference, необходимо указать два параметра:
- innerObject: Объект будет обернут внутри объекта PhantomReference.
- queue: Очередь, используемая для хранения этого объекта PhantomReference, когда его объект innerObject удаляется из памяти by GC.
ReferenceQueue<AnyObject> queue = new ReferenceQueue<>();
AnyObject innerObject = new AnyObject("Obj1");
PhantomReference phantomRef = new PhantomReference(innerObject, queue);
Все методы of PhantomReference наследуются от родительского класса.
// Methods inherited from parent.
public T get()
public void clear()
public boolean isEnqueued()
public boolean enqueue()
Метод PhantomReference.get() всегда возвращает null, цель которого - предотвратить доступ или попытку оживить объект, который почти был удален.
Возможно, вы задаетесь вопросом о характеристиках of PhantomReference, и теперь ваш вопрос заключается в том, для чего используется PhantomReference?
PhantomReference phantomRef = new PhantomReference(innerObject, queue);
В принципе, PhantomReference предоставляет вам возможность точно определить, когда его объект innerObject удаляется из памяти. Метод phantomRef.isEnqueued() возвращает true, что означает, что объект innerObject был удален из памяти. Когда объект innerObject удаляется из памяти, объект phantomRef будет помещен в очередь (queue).
Например: Если вам нужно выделить память для обработки больших видеофайлов, то использование PhantomReference - это хороший выбор. Сначала используйте PhantomReference для выделения памяти для обработки первого видео, затем вам нужно убедиться, что память была освобождена, прежде чем продолжать выделять память для обработки следующего видеофайла. Это уменьшает риск получения ошибки OutOfMemoryError.
Класс VideoProcessor имитирует обработку большого видеофайла:
VideoProcessor.java
package org.o7planning.phantomreference.ex;
public class VideoProcessor {
private String video;
public VideoProcessor(String video) {
this.video = video;
System.out.println("\nNew VideoProcessor: " + this.video);
}
public void process() {
System.out.println(" >>> Processing video: " + this.video);
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
System.out.println(" >>> Completed processing video: " + this.video);
}
// !IMPORTANT: Do not override finalize() method.
// (Java9+: If you override this method, PhantomReference will not work!!)
// @Override
// protected void finalize() throws Throwable {
// System.out.println("VideoProcessor is being removed from memory\n");
// super.finalize();
// }
}
PhantomReferenceEx1.java
package org.o7planning.phantomreference.ex;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
public class PhantomReferenceEx1 {
public static void main(String[] args) {
String[] videos = new String[] { "video1.mp4", "video2.mp4", "video3.mp4" };
ReferenceQueue<VideoProcessor> queue = new ReferenceQueue<VideoProcessor>();
for (String video : videos) {
VideoProcessor videoProcessor = new VideoProcessor(video);
PhantomReference<VideoProcessor> phantomRef = new PhantomReference<>(videoProcessor, queue);
videoProcessor.process();
videoProcessor = null;
// Call GC:
System.gc();
while (true) {
boolean isEnqueued = phantomRef.isEnqueued();
System.out.println(" phantomRef.isEnqueued: " + isEnqueued);
if (!isEnqueued) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
continue;
}
break;
}
}
System.out.println("\nObjects in the queue:");
Reference<? extends VideoProcessor> ref= null;
while((ref = queue.poll())!= null) {
System.out.println(ref);
}
}
}
Output:
New VideoProcessor: video1.mp4
>>> Processing video: video1.mp4
>>> Completed processing video: video1.mp4
phantomRef.isEnqueued: false
phantomRef.isEnqueued: true
New VideoProcessor: video2.mp4
>>> Processing video: video2.mp4
>>> Completed processing video: video2.mp4
phantomRef.isEnqueued: false
phantomRef.isEnqueued: true
New VideoProcessor: video3.mp4
>>> Processing video: video3.mp4
>>> Completed processing video: video3.mp4
phantomRef.isEnqueued: false
phantomRef.isEnqueued: true
Objects in the queue:
java.lang.ref.PhantomReference@5e265ba4
java.lang.ref.PhantomReference@156643d4
java.lang.ref.PhantomReference@123a439b
Java Basic
- Настройте java compiler для обработки вашего Annotation (Annotation Processing Tool)
- Программирование на Java для группы с помощью Eclipse и SVN
- Руководство Java WeakReference
- Руководство Java PhantomReference
- Сжатие и декомпрессия в Java
- Настройка Eclipse для использования JDK вместо JRE
- Методы String.format() и printf() в Java
- Синтаксис и новые функции в Java 8
- Регулярные выражения Java
- Руководство Java Multithreading Programming
- Библиотеки Java JDBC Driver для различных типов баз данных
- Руководство Java JDBC
- Получить значения столбцов, автоматически возрастающих при вставлении (Insert) записи, используя JDBC
- Руководство Java Stream
- Руководство Java Functional Interface
- Введение в Raspberry Pi
- Руководство Java Predicate
- Абстрактный класс и Interface в Java
- Модификатор доступа (Access modifiers) в Java
- Руководство Java Enum
- Руководство Java Annotation
- Сравнение и Сортировка в Java
- Руководство Java String, StringBuffer и StringBuilder
- Обработка исключений Java - Java Exception Handling
- Руководство Java Generics
- Манипулирование файлами и каталогами в Java
- Руководство Java BiPredicate
- Руководство Java Consumer
- Руководство Java BiConsumer
- Что мне нужно для начала работы с Java?
- История Java и разница между Oracle JDK и OpenJDK
- Установить Java в Windows
- Установите Java в Ubuntu
- Установите OpenJDK в Ubuntu
- Установить Eclipse
- Установите Eclipse в Ubuntu
- Быстрое изучение Java для начинающих
- История бит и байтов в информатике
- Типы данных в java
- Битовые операции
- Команда if else в Java
- команды switch в Java
- Циклы в Java
- Массивы (Array) в Java
- JDK Javadoc в формате CHM
- Наследование и полиморфизм в Java
- Руководство Java Function
- Руководство Java BiFunction
- Пример Java encoding и decoding с использованием Apache Base64
- Руководство Java Reflection
- Java Удаленный вызов методов - Java RMI
- Руководство Программирование Java Socket
- Какую платформу я должен выбрать для разработки приложений Java Desktop?
- Руководство Java Commons IO
- Руководство Java Commons Email
- Руководство Java Commons Logging
- Понимание Java System.identityHashCode, Object.hashCode и Object.equals
- Руководство Java SoftReference
- Руководство Java Supplier
- Аспектно-ориентированное программирование Java с помощью AspectJ (AOP)
Show More
- Руководства Java Servlet/JSP
- Руководства Java Collections Framework
- Java API для HTML, XML
- Руководства Java IO
- Руководства Java Date Time
- Руководства Spring Boot
- Руководства Maven
- Руководства Gradle
- Руководства Java Web Services
- Руководства Java SWT
- Руководства JavaFX
- Руководства Oracle Java ADF
- Руководства Struts2 Framework
- Руководства Spring Cloud