RFR: 8289220: Locale.forLanguageTag throws NPE due to soft ref used in locale cache being cleared [v6]

Daniel Jeliński djelinski at openjdk.org
Wed Jun 7 11:59:57 UTC 2023


On Wed, 7 Jun 2023 03:37:26 GMT, SUN Guoyun <duke at openjdk.org> wrote:

>> command: make test CONF=fastdebug JTREG="VM_OPTIONS=-Xcomp" TEST=gc/TestAllocHumongousFragment.java
>> error info: 
>> 
>> Caused by: java.lang.NullPointerException: Cannot invoke "sun.util.locale.BaseLocale.getVariant()" because "base" is null
>> at java.base/java.util.Locale.forLanguageTag(Locale.java:1802)
>> at java.base/sun.util.cldr.CLDRBaseLocaleDataMetaInfo.<clinit>(CLDRBaseLocaleDataMetaInfo.java:41)
>> ... 24 more
>> 
>> Note that the test runs with -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot and SoftReferences are involved (LocaleObjectCache uses SoftReferences, used by printf method called in getRandomInstance(Utils.java:511)).
>> 
>> Maybe we have to deal with the case where the getBaseLocale() return value is null. the call stack is:
>> 
>> 	at java.base/sun.util.locale.LocaleObjectCache.get(LocaleObjectCache.java:64)
>> 	at java.base/sun.util.locale.BaseLocale.getInstance(BaseLocale.java:169)
>> 	at java.base/sun.util.locale.InternalLocaleBuilder.getBaseLocale(InternalLocaleBuilder.java:524)
>> 	at java.base/java.util.Locale.forLanguageTag(Locale.java:1874)
>> 
>> in LocaleObjectCache.java:64
>> 
>> 	 62             if (key == null || newVal == null) {                                
>> 	 63                 // subclass must return non-null key/value object               
>> 	 64                 return null; // run here
>> 	 65             }
>
> SUN Guoyun has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8289220: Locale.forLanguageTag throws NPE due to soft ref used in locale cache being cleared

In its current form the `BaseLocale.Cache.createObject` function can return `null`; the object returned by `BaseLocale.Key.normalizeKey(key)` holds a soft reference to locale, and by the time `getBaseLocale` is called, the reference may be cleared.

`Key` only uses `SoftReferences` because it must not hold a reference to the object returned by `createObject`. We could refactor `createObject` to return a clone of the `BaseLocale` referenced by `Key`, and then `Key` would not need to use `SoftReference`s.

That being said, the number of long-lived `BaseLocale` objects is very limited; we only keep them in Locale, LocaleKey, and Locale.CONSTANT_LOCALES. Unless I'm missing something, we could solve this problem by removing `BaseLocale` caching, and improve performance at the same time.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/14211#issuecomment-1580652895


More information about the core-libs-dev mailing list