<div dir="auto"><div>And maybe I am not clear, I am saying that the idea of a toggle is not really something I want. It feels like a bad bandaid. A WR to a value class already is confusing, and to have a toggle, let alone one that defaults to being permissive rather than restrictive, is worse in my eyes.</div><div dir="auto"><br></div><div dir="auto">And even if it defaulted to fail, what purpose does the toggle serve? Toggles like this make sense when we want to slowly wean a large number of users off of some previously-acceptable behaviour. But I don't think there were many people (of the already small number of WR users) making WR's of Value Classes. In this case, the exception + JFR approach is the only one thatmakes sense to me thus far. But of course, I say that without a prototype in hand to test my claims.</div><div dir="auto"><br><div class="gmail_quote gmail_quote_container" dir="auto"><div dir="ltr" class="gmail_attr">On Sat, Dec 13, 2025, 12:11 AM David Alayachew <<a href="mailto:davidalayachew@gmail.com">davidalayachew@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>Oh I understood you the first time.</div><div dir="auto"><br></div><div dir="auto">I don't think your idea is bad, I just prefer the exception idea better. My response was to say that, even though I think sticking with IdentityException is best, your idea about warning is good too **if done as well as exceptions**.</div><div dir="auto"><br></div><div dir="auto">Like you said, there are many people who do catch (Exception e) out there, and this will silently give them new and potentially unwanted behaviour, even in spite of going with #4. Hence my point -- let's also trigger a JFR Event. That way, catch-all or not, you get notified.<br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Fri, Dec 12, 2025, 6:11 PM Glavo <<a href="mailto:zjx001202@gmail.com" target="_blank" rel="noreferrer">zjx001202@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi David,<div><br></div><div>I think I didn't explain myself very clearly. My ideal default behavior would be to make WR a strong reference and print a warning.</div><div><br></div><div>Or, to be more specific, I hope its behavior is configurable (controlled by a parameter similar to --illegal-native-access). </div><div>I would like it to have at least three modes of behavior:<br><br>1. allow: silently treat WR as a strong reference<br>2. warn: treat WR as a strong reference and emit a warning<br>3. deny: throw an IdentityException<br><br>The default should be behavior 1 or 2, and only in the relatively distant future should we consider changing the default to 3.</div><div><br></div><div>Glavo</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Dec 13, 2025 at 6:40 AM David Alayachew <<a href="mailto:davidalayachew@gmail.com" rel="noreferrer noreferrer" target="_blank">davidalayachew@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div>I don't agree that #4 is the worst option -- in fact, I think it is the best of the 4. Though, my opinion might change with a prototype to play with.</div><div dir="auto"><br></div><div dir="auto">But regardless, I do agree that some sort of warning would be good. Preferrably a JFR Event. Like Glavo said -- there are a lot of catch-all's out there, so having the event **as well as** the exception sounds best to me.</div><div dir="auto"><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Fri, Dec 12, 2025, 4:17 PM Glavo <<a href="mailto:zjx001202@gmail.com" rel="noreferrer noreferrer" target="_blank">zjx001202@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi Brian,<div><br>This answer was unexpectedly simple to me.<br><br>Of course, I understand the common usage of WR. I clearly know that the semantics I mentioned, while allowing some code to work, do not align with the original intent of using WR in those contexts.</div><div><br>However, I believe throwing an exception is the worst option—far worse than letting the WR turn into a strong reference.<br>This is because users have long had the obligation to handle OOM; they can proactively trigger OOM for testing by reducing heap size or other means. </div><div>In contrast, users have never had the obligation to handle IdentityException, nor any way to test it. As a result, an unexpected exception could lead the program into untested code paths.<br></div><div>I even think throwing an exception is worse than directly letting the VM crash, because some catch blocks might silently swallow the IdentityException, making it much harder for users to understand why their program behaved abnormally.<br><br>For me, a more ideal approach would be to print a warning by default when creating a WR for a value object—at least this would make it easier for developers to notice the issue.</div><div><br></div><div>Glavo</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Dec 13, 2025 at 2:39 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" rel="noreferrer noreferrer noreferrer" target="_blank">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div>
<font size="4" face="monospace">Indeed, many hours of discussion
went into this decision. <br>
<br>
The basic problem is that all of the obvious answers are either
surprising or surprisingly expensive. We considered the following
four approaches:<br>
<br>
1. Allow `new WR(value)`, which is cleared on birth. <br>
2. Allow `new WR(value)`, which is never cleared.<br>
3. Allow `new WR(value)`, which is cleared when all identities
reachable through the value are become weakly reachable.<br>
4. Throw, and encourage implementations that are built on WR
(such as WHM) to offer their own ways of dealing with values. <br>
<br>
You can readily see how (1) would not be what anyone expects. <br>
<br>
You are arguing for (2). While this initially seems credible, its
primary appeal is "yeah it's useless, but it won't break things
that just throw everything in a WHM". But it is actually worse
than useless! The purposes of WRs is to not unnecessarily pin
things in memory. But a WR that is never cleared does exactly
that; if the referent holds identities, then it effectively
becomes a strong reference. <br>
<br>
(3) is a more principled answer, but is very expensive to
implement, and its still not clear that this is what people will
expect.<br>
<br>
(4) is honest, if inconvenient. Given that the majority of uses
of WR are through higher-level constructs like WHM, which have
more flexibility to choose the semantics that is right for their
more restricted domain, it made sense to make this a WHM (and
friends) problem than a WR problem (given that there were no good
answers at the WR level.)<br>
</font><br>
<div>On 12/12/2025 10:02 AM, Glavo wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">Hi,
<div><br>
In the current draft of JEP 401, I saw the following
statement:</div>
<div><br>
</div>
<div>> The garbage collection APIs in java.lang.ref and
java.util.WeakHashMap do not allow developers to manually
manage value objects in the heap.</div>
<div>> Attempts to create Reference objects for value objects
throw IdentityException at run time.</div>
<div><br>
</div>
<div>We could clearly have pretended that all value objects
exist forever and are never collected, so that Reference or
WeakHashMap would still work with value objects.</div>
<div>Obviously, doing so would break far fewer existing codes,
whereas having them directly throw IdentityException would
break a lot more code.</div>
<div><br>
</div>
<div>As an analogy, I think this is very similar to ThreadLocal
on virtual threads. Although virtual threads make many use
cases of ThreadLocal low-performance and high-memory, </div>
<div>Project Loom did not outright forbid users from using
ThreadLocal on virtual threads, yet Project Valhalla chose to
break this (admittedly inefficient) writing style.</div>
<div><br>
I don’t understand why Project Valhalla made this choice. Has
there been any related discussion in the past? I’m really
eager to know the reasoning behind this decision.</div>
<div><br>
</div>
<div>Glavo</div>
</div>
</blockquote>
<br>
</div>
</blockquote></div>
</blockquote></div></div></div>
</blockquote></div>
</blockquote></div></div></div>
</blockquote></div></div></div>