Предотвращение утечки собственной памяти путем настройки сборщика мусора? - PullRequest
3 голосов
/ 13 января 2012

Допустим, я пишу API в Java, который ссылается на некоторые нативные библиотеки C, которые требуют явного вызова деструкторов.Если деструкторы не вызываются, у меня заканчивается собственная память.

Есть ли способ защитить пользователей моего API от явного вызова деструкторов, заставляя сборщик мусора вызывать деструкторы каким-либо образом?(возможно, основываясь на некоторой оценке размера используемой собственной памяти?)

Я знаю, что в Java нет сборщика мусора как части Java API, но, возможно, есть какой-то способ получить этореализованы?

Ответы [ 3 ]

3 голосов
/ 13 января 2012

Одной из альтернатив, если у вас есть контроль над созданием ваших объектов, является обращение к ним с помощью WeakReference с помощью конструктора, который принимает ReferenceQueue. Когда они выйдут из области видимости, ссылка будет поставлена ​​в очередь, и вы сможете создать собственный поток, опрашивающий очередь и вызывающий некоторую функцию очистки.

Почему? Ну, это немного более эффективно, чем добавление финализаторов в ваши классы (потому что это заставляет gc выполнять их специальную обработку).

Редактировать : следующие два (варианты одной и той же статьи) описывают это: http://java.sun.com/developer/technicalArticles/javase/finalization/ http://www.devx.com/Java/Article/30192

У Питера Лоури очень хорошее замечание, когда он говорит:

Несмотря на это, ожидание очистки ГХ может быть неэффективным, и вы можете захотеть использовать средства явной очистки ресурса, если это необходимо.

Всякий раз, когда вы можете предположить, что ваши пользователи работают на Java7, взгляните на java.lang.AutoCloseable , поскольку это поможет им сделать это автоматически при использовании новой попытки с ресурсами.

2 голосов
/ 13 января 2012

В дополнение к использованию finalize () вам может потребоваться активировать GC, если у вас закончились ресурсы для выполнения вызова, однако GC не был запущен.

Эта проблема возникла в ByteBuffer.allocateDirect ().Ему нужен GC для очистки его ByteBuffers. Однако вы можете достичь своей максимальной прямой памяти до того, как GC сработает, поэтому код должен обнаружить это и явно вызвать System.gc().

Тем не менее, ожидаяочистка GC может быть неэффективной, и вы можете захотеть предоставить средства для явной очистки ресурса, если это необходимо.

1 голос
/ 13 января 2012

Сборщик мусора вызовет finalize() объектов Java, когда объект Java собирается стать GCd, и внутри финализации вы можете вызвать деструктор. Просто создайте новый Java-объект для каждого деструктора, который необходимо вызвать, и сохраняйте ссылку на этот Java-объект до тех пор, пока вы не захотите вызвать деструктор.

На практике finalize() будет вызываться рано или поздно (даже если технически Java не гарантирует, что какой-либо конкретный объект когда-либо будет GCd). Единственное исключение - если объект все еще существует, когда процесс завершается: тогда он действительно может никогда не получить GCd.

...