Освобождение памяти, выделенной родными библиотеками в Java - PullRequest
0 голосов
/ 07 ноября 2018

Если вы выполняете код, который выполняет вызовы в нативную библиотеку на Java, каков обычный способ освобождения памяти, выделенной этими библиотеками, когда выделение памяти должно продолжаться в течение всего срока службы объекта? В C ++ я бы использовал деструкторы, но в Java их никогда не было, а у теперь их еще меньше .

Особый случай, который меня больше всего интересует, это JOCL , где у меня есть объект, который оборачивает скомпилированное ядро ​​OpenCL и все его аргументы, которые всегда одинаковы. Структуры, представляющие скомпилированное ядро ​​и аргументы, все размещаются на стороне библиотеки, и JOCL предоставляет метод clReleaseMemObject, который вы вызываете для уменьшения счетчика ссылок, указывающего, когда объект должен быть удален (обратите внимание, что это немного отличается от прямого освобождения памяти, но в этом случае я не думаю, что это так).

Я предполагаю, что если объект все еще присутствует, когда программа завершается, все очищается ОС, но я не очень уверен насчет объектов, созданных в потоке. Итак:

  1. Если вы хотите, чтобы собственная память была освобождена при сборке мусора, есть ли подходящее место для вызова метода, который освобождает эту память?

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

1 Ответ

0 голосов
/ 07 ноября 2018

Что вы можете сделать, это использовать Очиститель . Это более официальный API в Java 9, но доступен в Java 1.4 +.

По сути, вы даете ему Runnable для выполнения при очистке ресурса.

Одним из преимуществ использования Cleaner является то, что вы можете вызывать его для детерминированной очистки, но если вы забудете или не сделаете этого, GC вызовет его после запуска.

Не существует безопасного способа очистки объекта, когда поток умирает, поскольку объект Thread может жить в течение жизни программы, даже если он мертв. Более простой подход состоит в том, чтобы очистить, поскольку вы знаете, что это не нужно, или после того, как GC определит, что это не требуется.

Другой подход заключается в использовании ссылочной очереди и фонового потока. Это не так элегантно, но работает в Java 8 и более поздних версиях.

...