Что такое Java-эквивалент GC.KeepAlive .net?JAVA

Программисты JAVA общаются здесь
Anonymous
Что такое Java-эквивалент GC.KeepAlive .net?

Сообщение Anonymous »

.NET имеет функцию GC.KeepAlive(Object). Его единственная цель — обеспечить продолжительность жизни объекта, на который ссылаются, до тех пор, пока поток кода не достигнет вызова.

Обычно в этом нет необходимости, если только он не взаимодействует с собственным кодом.

У меня есть ситуация, когда у меня есть граф объектов C++, доступ к которому осуществляется через JNI, где некоторые корневые объекты необходимо поддерживать в живых, чтобы поддерживать жизнь дочерних элементов. И корневые, и дочерние объекты имеют зеркала в среде JVM. Однако если корневой объект собирается и освобождается на стороне C++ (посредством финализатора, созданного SWIG), дочерние объекты станут недействительными, поскольку их поддерживающий объект C++ будет освобожден.

Это можно решить, обеспечив, чтобы локальные переменные, которые являются корневыми в графе объектов, имели время жизни, превышающее время последнего использования дочернего объекта. Поэтому мне нужна идиоматическая функция, которая ничего не делает с объектом, но не будет оптимизирована или перемещена (например, выведена из цикла). Это то, что GC.KeepAlive(Object) делает в .NET.

Каков приблизительный эквивалент в Java?

PS: возможно, какой-нибудь иллюстративный код:

Код: Выделить всё

class Parent {
long ptr;
void finalize() { free(ptr); }
Child getChild() { return new Child(expensive_operation(ptr)); }
}

class Child {
long ptr;
void doStuff() { do_stuff(ptr); }
}

// BAD CODE with potential for SIGSEGV
for (Parent p : getParents()) {
p.getChild().doStuff();
}
Проблема в том, что GC, освобождающий Parent p, освободит память, выделенную для Child, пока выполняется doStuff. Было замечено, что GC делает это на практике. Возможное исправление, если GC.KeepAlive был доступен:

Код: Выделить всё

// BAD CODE with potential for SIGSEGV
for (Parent p : getParents()) {
p.getChild().doStuff();
GC.KeepAlive(p);
}
Я мог бы, например. вызовите toString на p, но я не буду ничего делать с его выводом. Я мог бы временно ввести p в массив, но откуда мне знать, что JVM не отбросит хранилище? И т. д.

Вернуться в «JAVA»