Fwd: Feedback about StableValues(Preview)

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Sep 3 00:03:00 UTC 2025


On 03/09/2025 00:54, david Grajales wrote:
> Hello Maurizio. Thanks for the quick response and explanation.
>
> So, in short the stable values are not mean for very dynamic scenarios 
> because the API prioritize performance and efficiency at runtime and 
> sacrifices flexibility in exchange; which translates as " the keys or 
> at least the size of the stableValue must be know at compile time".

I think so -- e.g. to get better performance than a concurrent hash map 
you need to give up some flexibility. If you don't, that's fine, but 
then concurrent hashmap is likely the best implementation for your use case.

I think the main use cases for the stable lists and maps we provide is 
to deal with groups of stable values. E.g. think of a situation where a 
class has maybe 10 fields like Logger -- fields that are lazily 
initialized. Do you declare 10 holder classes? Or 10 stable values, each 
with its own update logic? With a stable map you can actually group 
these stable values together -- which means you only need one lambda, 
not 10.

Maurizio

>
> Best regards.
>
> El mar, 2 de sept de 2025, 6:14 p.m., Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com> escribió:
>
>     Hi David,
>     Thanks for your feedback.
>
>     The factories that we provide, like StableValue::list and
>     StableValue::map cover common cases where the list/map elements
>     are known upfront, but should be computed lazily.
>
>     In other words you might think of these factories as lazy variants
>     of List::of and Map::of. Both kinds of factories return an
>     unmodifiable collection -- that is a collection whose size is
>     fixed, and that rejects update operations.
>
>     I understand that you would like to create a "stable" map, whose
>     key/values are not known upfront -- more specifically, where the
>     keys are only known dynamically.
>
>     I believe in these cases the "win" for using a stable map in the
>     first place is much less obvious. If the map can grow dynamically
>     (e.g. because you don't know how many entries you might be adding
>     to it) you are probably looking at an implementation that has some
>     way to "resize" itself -- which makes using something like a
>     stable construct much harder. For instance, adding new entries on
>     a map might cause the underlying array of buckets to be
>     reallocated, and existing entries to be rehashed in the new
>     (larger) bucket array. This means that the bucket array itself
>     will need to be updated several times during the lifecycle of the
>     map, making it not stable (remember: stable means "updated at most
>     once").
>
>     If some constraints are relaxed, e.g. maybe you know how many
>     entries you are going to add in your map -- that might make the
>     problem easier, as now we're back in a situation where we now the
>     size of the underlying storage. For instance one can have a
>     specialized hash table implementation backed by a linear array (of
>     an appropriate size), and then use linear probing to store entries
>     in the linear array. Since the size is bounded, the size of the
>     entries linear array is also bounded, and we can then make that
>     linear array stable (e.g. use a stable list).
>
>     Since such a "fixed size" hash map would be quite specialized, we
>     did not see yet enough motivation for adding it to the JDK --
>     especially given that developers should be able to define such
>     constructs on top of the StableValue API (in fact _all_ the
>     existing provided factories are defined in terms of the Stable
>     Value API).
>
>     But it's not just about whether the size is known or not -- in
>     order for the JVM to be able to apply any sort of constant-folding
>     optimization to the map access, you need the key to be a constant
>     (e.g. either some compile-time constant, or the value of a static
>     final field, or the contents of some other stable value). Only
>     then we can fold the entire map access expression (if we're
>     lucky). But in the example you provide, the key provided to
>     Map::get is just a random class name you get from the current
>     stack. So there's very little for the JIT to optimize here. If the
>     input (the key) is not known, then the access expression
>     (Map::get) cannot be optimized.
>
>     In other words, the case of a fully dynamic list/map that you
>     propose just doesn't seem a great fit for stability, in the sense
>     that you likely won't get any performance improvement (over a
>     concurrent hash map) by using some sort of stable map there.
>
>     Maurizio
>
>
>     On 02/09/2025 02:45, david Grajales wrote:
>>
>>
>>     ---------- Forwarded message ---------
>>     De: *david Grajales* <david.1993grajales at gmail.com>
>>     Date: lun, 1 sept 2025 a la(s) 8:43 p.m.
>>     Subject: Feedback about StableValues(Preview)
>>     To: <core-libs-dev at openjdk.org>
>>
>>
>>     Subject: Feedback and Questions on JEP 8359894 - Stable Values API
>>
>>     Dear Java core-libs development team,
>>
>>     Please accept my sincere gratitude and compliments for your
>>     ongoing dedication to improving the Java platform. The continuous
>>     innovation and thoughtful evolution of Java is truly appreciated
>>     by the developer community.
>>
>>     I have been experimenting with the Stable Values API (JEP
>>     8359894) in a development branch of a service at my company, and
>>     I would like to share some observations and seek your guidance on
>>     a particular use case.
>>
>>
>>         Current Implementation
>>
>>     Currently, I have a logging utility that follows a standard
>>     pattern for lazy value computation:
>>
>>
>>     class DbLogUtility {
>>         private static final ConcurrentMap<String, Logger>
>>     loggerCache = new ConcurrentHashMap<>();
>>
>>         private DbLogUtility(){}
>>
>>         private static Logger getLogger() {
>>             var className =
>>     Thread.currentThread().getStackTrace()[3].getClassName();
>>             return loggerCache.computeIfAbsent(className,
>>     LoggerFactory::getLogger);
>>         }
>>         public static void logError(){
>>             //.... implementation detail
>>         }
>>     }
>>
>>
>>         Challenge with Stable Values API
>>
>>     When attempting to migrate this code to use the Stable Values
>>     API, I encountered a fundamental limitation: the API requires
>>     keys to be known at compile time. The current factory methods
>>     (|StableValue.function(Set<K>, Function)| and
>>     |StableValue.intFunction(int, IntFunction)|) expect predefined
>>     key sets or bounded integer ranges.
>>
>>     This design constraint makes it challenging to handle dynamic key
>>     discovery scenarios, which are quite common in enterprise
>>     applications for:
>>
>>       * Logger caching by dynamically discovered class names
>>       * Configuration caching by runtime-determined keys
>>       * Resource pooling with dynamic identifiers
>>       * Etc.
>>
>>
>>         Questions and Feedback
>>
>>      1. *Am I missing an intended usage pattern?* Is there a
>>         recommended approach within the current API design for
>>         handling dynamic key discovery while maintaining the
>>         performance benefits of stable values?
>>      2.  Would you consider any of these potential enhancements:
>>           * Integration of stable value optimizations directly into
>>             existing collection APIs (similar to how some methods
>>             have been added to List and Map interfaces for better
>>             discoverability)
>>           * A hybrid approach that provides stable value benefits for
>>             dynamically discovered keys
>>      3. Do you envision the Stable Values API as primarily serving
>>         compile-time-known scenarios, with dynamic use cases
>>         continuing to rely on traditional concurrent collections?
>>
>>     Thank you for your time and consideration. I would be grateful
>>     for any guidance or clarification you might provide on these
>>     questions. If there are planned enhancements or alternative
>>     patterns I should consider, I would very much appreciate your
>>     insights.
>>
>>     Best regards, and always yours.
>>
>>     David Grajales Cárdenas.
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20250903/9b0abd86/attachment-0001.htm>


More information about the amber-dev mailing list