You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This usage of initial inside final class Atomic[A] prevents it from being garbage collected. The only other usage is inside val unsafe = new AtomicReference[A](initial), but that is mutable so if it wasn't for such toString implementation, it would have eventually be garbage collected after the referenced value is changed using any of the mutation methods.
It might not be a problem for cases when the initial value for Ref is not a large object, but in our case we happen to initiate it with very large values. The fact that those values are kept in memory even after the ref is modified, makes us waste gigabytes of memory with data that we will never access.
The previous toString version used to print the current value:
overridedeftoString:String=s"Ref(${value.get})"
@hearnadam argues that this is unnecessary, which I can relate to, especially since it's not suspended. However, I think printing the initial value is arguably even less useful. It is possible to keep this behaviour it by memoizing initial.toString though:
I think it's fair to assume that in many cases the string representation of the initial will be considerably smaller than the actual value. But this way the initial value can be garbaged collected once the ref is modified, so there is much less memory usage. Alternatively, toString could be simplified even further and just not print any content of the wrapped value (initial or current). I guess the old behavior can also be brought back with usafe.get, though I agree with @hearnadam that it's not worth it
The text was updated successfully, but these errors were encountered:
Hello 👋
This issue is introduced in version
2.1.15
with #9500.The root cause is this part:
This usage of
initial
insidefinal class Atomic[A]
prevents it from being garbage collected. The only other usage is insideval unsafe = new AtomicReference[A](initial)
, but that is mutable so if it wasn't for suchtoString
implementation, it would have eventually be garbage collected after the referenced value is changed using any of the mutation methods.It might not be a problem for cases when the initial value for
Ref
is not a large object, but in our case we happen to initiate it with very large values. The fact that those values are kept in memory even after the ref is modified, makes us waste gigabytes of memory with data that we will never access.The previous
toString
version used to print the current value:@hearnadam argues that this is unnecessary, which I can relate to, especially since it's not suspended. However, I think printing the initial value is arguably even less useful. It is possible to keep this behaviour it by memoizing
initial.toString
though:I think it's fair to assume that in many cases the string representation of the
initial
will be considerably smaller than the actual value. But this way the initial value can be garbaged collected once the ref is modified, so there is much less memory usage. Alternatively,toString
could be simplified even further and just not print any content of the wrapped value (initial or current). I guess the old behavior can also be brought back withusafe.get
, though I agree with @hearnadam that it's not worth itThe text was updated successfully, but these errors were encountered: