Fwd: Feedback about StableValues(Preview)

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Sep 2 23:14:51 UTC 2025


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/d39b8622/attachment.htm>


More information about the amber-dev mailing list