I create an object called Foo
. When I create a lambda or method reference called Action
, the Action
object holds a reference to Foo
.
I pass the action to another class. But if I hold it as a weak reference, it gets gc immediately, because no one stores another reference to Action
.
But if i hold it as a strong reference, the Foo
can't be gc, because Action
holds a referene to it.
So memory leaks happen and I want to prevent it.
My question is: how can I hold a reference to Action
without preventing gc of Foo
.
Example:
Interface Action {
void invoke();
}
Class Foo() {
public void someMethod() {
....
}
}
Class Holder() {
WeakRefrence<Object> foo;
public Action action;
void register(Object source, Action a) {
foo = new WeakReference(source);
??? how can i hold the action without prevent source to gc able.
}
}
main() {
Holder holder = new Holder();
Foo foo = new Foo();
Action action = foo::someMethod;
holder.register(foo,action);
action = null;
System.gc();
//only the holder store reference to action.
//if i store in holder as weak reference i cannot invoke it any more cause it get gc.
//foo = null;
//System.gc();
//if i grab action in holder as strong refrence the foo cant be gc cause action hold refernce to it.
holder.action.invoke();
}
You have to separate the action from the weakly referenced target. You should always keep in mind that lambdas are intended to specify behavior only.
class Foo {
public void someMethod() {
System.out.println("Foo.someMethod called");
// ....
}
}
class Holder<T> extends WeakReference<T> {
private final Consumer<T> action;
Holder(Consumer<T> action, T target) {
super(target);
this.action=action;
}
public void performAction() {
T t=get();
if(t!=null) action.accept(t);
else System.out.println("target collected");
}
}
class Test {
public static void main(String... arg) {
Foo foo = new Foo();
Holder<Foo> holder = new Holder<>(Foo::someMethod, foo);
System.gc(); // we are still referencing foo
holder.performAction();
foo = null;
System.gc(); // now we have no reference to foo
holder.performAction();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With