Прямая память Java: использование sun.misc.Cleaner в пользовательских классах - программирование

Прямая память Java: использование sun.misc.Cleaner в пользовательских классах

В Java память, выделяемая прямыми буферами nio, освобождается экземплярами sun.misc.Cleaner, некоторые специальные phantom ссылки, которые более эффективны, чем завершение объекта.

Является ли этот механизм очистки жестко закодированным в JVM только для подклассов прямого буфера или можно также использовать очистители в пользовательских компонентах (например, для записи собственного прямого байтового буфера)?

Здесь я не говорю о том, чтобы извлечь поле чистого существующего nio-прямого буфера. Я не говорю о том, чтобы вручную освободить память. Речь идет о написании нового класса, который выделяет прямую память и эффективно и автоматически очищается механизмом сбора мусора.

4b9b3361

Ответ 1

Потратив больше времени на чтение документа API (http://docs.oracle.com/javase/7/docs/api/java/lang/ref/package-summary.html), я думаю, у меня есть более подробный ответ:

1) можно повторно использовать sun.misc.Cleaner для эффективной очистки ваших собственных пользовательских классов. Вы объявляете уборщика, вызвав предоставленный метод factory:

sun.misc.Cleaner.create(Object ob, Runnable cleanup);

В течение некоторого времени я не мог заставить его работать правильно, потому что я был достаточно глуп, чтобы определить исполняемый код очистки моего чище как анонимного класса, который содержал (сильную) ссылку на мой объект референта, когда-либо "phantom достижимый"...

2) Нет другого способа реализовать такую ​​эффективную очистку (даже с помощью ссылок phantom)

В действительности поток обработчика ссылок обрабатывает экземпляры sun.misc.Cleaner особым образом:

// Fast path for cleaners
if (r instanceof Cleaner) {
    ((Cleaner)r).clean();
    continue;
}

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

Ответ 2

Если вы полагаетесь на что-либо в пакете sun.misc, вы рискуете исчезнуть и сломать свой код. Некоторые части более стабильны, чем другие, но часто это плохая идея (devil advocate: многие методы в sun.misc.Unsafe на самом деле реализованы с помощью JVM intrinsics, что делает их быстрее, чем написанный пользователем JNI-код).

В этом случае я думаю, что это плохая идея: Cleaner - одна из возможных реализаций очистки через PhantomReference. Есть и другие; Google для примеров. В этом случае вы можете посмотреть исходный код самого Cleaner в качестве примера того, как использовать ссылки phantom.

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