2015-10-23 3 views
3

Я нахожусь в положении, где хочу передать byte[] в собственный метод через JNA. Все примеры, которые я нашел об этом, либо используют экземпляр Memory, либо используют выделенный выделенный ByteBuffer, а затем получают Pointer.Проблема с утечкой памяти с использованием класса памяти JNA?

Однако, когда я читаю документы, они говорят, что основная родную память - который, как я понимаю, он выделяется «от книг» за пределы виртуальной машины Java управляемого кучи - эти объекты Java потребляют только получить освобожденные, когда вызывается метод объекта finalize().

Но когда этот финализатор получает вызов, он не имеет ничего общего с тем, когда объекты выходят за рамки. Они могут долго болтаться, прежде чем сборщик мусора фактически завершает их. Таким образом, любая собственная память, которую они выделили, останется распределенной в течение произвольного времени после выхода из сферы действия. Если они держатся за большую память и/или если есть много объектов, которые мне кажутся, у вас будет эффективная утечка памяти. Или, как минимум, потребление стационарной памяти потенциально намного выше, чем казалось бы, должно быть. Другими словами, подобное поведение по сравнению с тем, что описано в JNA/ByteBuffer not getting freed and causing C heap to run out of memory

Есть ли какой-либо путь вокруг этой проблемы с JNA? Или мне нужно отказаться от JNA для этого и использовать JNI вместо этого, чтобы я мог использовать JNIEnv::GetByteArrayElements(), так что нет необходимости в каких-либо выделениях памяти «от книг», которые могут сохраняться сколь угодно долго? Допустимо ли это для подкласса Memory, чтобы получить доступ к методу dispose() и использовать его для освобождения основной памяти на моей временной шкале вместо временной шкалы GC? Или это вызовет проблемы при запуске финализатора?

+0

Я бы не стал беспокоиться об этом - сборщик мусора будет вызываться всякий раз, когда куча будет заполнена, и больше памяти будет выделено, поэтому она запускается только тогда, когда это необходимо. – Kenney

+1

Проблема, как я понимаю, заключается в том, что такие объекты занимают минимальное пространство памяти с поддержкой GC, но могут занимать значительно более неуправляемое пространство * процесса * памяти. Таким образом, * процесс * может занимать много памяти, прежде чем GC увидит достаточно «кучи» кучи, чтобы дорабатывать вещи. См. Ссылку, которую я добавил в описании основного вопроса. – QuantumMechanic

+0

Ах да .. согласно ссылке на связанную вами страницу, это [известная ошибка] (http://bugs.java.com/view_bug.do?bug_id=4469299), открытая с 2001 года, все еще не разрешена. Я полагаю, что короткий ответ на ваш вопрос - «да». Одно из последних предложений: вместо регулярного вызова 'System.gc()', как предложено в обходных решениях, вы можете вызвать его из собственного кода, если 'malloc' терпит неудачу. – Kenney

ответ

3

ЮНА обеспечивает Memory.disposeAll() и Memory.dispose() явно свободной памяти (последняя требует подкласс Memory), так что если вы сделать когда-либо столкнуться давление памяти, для которых регулярные GC не является достаточным, у вас есть какой-то дополнительный контроль доступны.

Смежные вопросы