JDK-4405807 : ResourceBundle holds ClassLoader references using SoftReference (not weak)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.3.0,1.3.1,1.4.1_02,1.4.2_03
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,solaris_2.6,windows_nt,windows_2000 generic,solaris_2.6,windows_nt,windows_2000
  • CPU: generic,x86
  • Submitted: 2001-01-18
  • Updated: 2004-07-13
  • Resolved: 2004-03-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
1.4.2_06 06Fixed
Related Reports
Relates :  
Relates :  
From examining the code for java.util.ResourceBundle (circa JDK 1.3) it seems that it holds onto both bundle values and classloader keys using soft references. For the bundle values, this definitely makes sense--parsing bundles takes time and they should be cached, but they can be reloaded if memory requirements make that necessary. But I do not understand why the classloader is held (by ResourceBundle.ResourceCacheKey.loaderRef) as a soft reference. Wouldn't a weak reference be better?

For example, create some classloader; load a bundle through that classloader and use some messages in it; now discard all references to the bundle *and*  to the classloader. The classloader cannot now be garbage-collected because ResourceBundle is still holding onto it (until the system runs out of memory, I guess), as I found out using a heap analyzer: I had managed to clear all references to some old classloaders except for those held by ResourceBundle. (If the loader ref were a WeakReference, then after a normal GC the unused classloader should be released.) There is no reason I can think of to cache bundles from the now softly-referenced classloader since no one else even has a handle on it.

Affected also by #4405789 which says that JAR files are not reloadable in new URLClassLoader's until old ones are GC'd. With ResourceBundle holding onto the old loaders it is impossible to GC the old ones reliably, and thus very difficult to reload JARs into a running application, as well as leaking some memory.

Observed on RedHat Linux with JDK 1.3 FCS. Affects NetBeans/Forte for Java application (dynamic reloadability of plug-in modules).

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.2_06 generic tiger-beta2 FIXED IN: 1.4.2_06 tiger-beta2 INTEGRATED IN: 1.4.2_06 tiger-b43 tiger-beta2 VERIFIED IN: 1.4.2_06

EVALUATION Name: nl37777 Date: 01/30/2002 Targeted for Hopper. ====================================================================== Name: nl37777 Date: 04/17/2002 The submitter is right in that weak references should be used for the class loaders. There are additional related issues: Since we were using a SoftCache and used class loaders also as the cache value to indicate that no resource bundle was found, there were soft references to class loaders on the value side too. Also, if a class loader is garbage collected, we did nothing to get rid of related resource bundles - they still hung around until we totally ran out of memory and the soft references were cleared. I changed the implementation along the following lines: - Use weak references for the class loader in the cache key. - Use a HashMap instead of a SoftCache for the cache. SoftCache provided us with soft references for the values, which aren't always appropriate, and with automatic removal of entries when memory was getting tight. We now handle both directly. - Use soft references directly for resource bundles as values in the cache. - Use our own scheme to remove entries from the cache when either the resource bundle values in the cache or the requested class loaders get garbage collected. - Use a constant NOT_FOUND object as the cache value where a resource bundle couldn't be found. Previously we were using the requested class loader (if not null) so that the SoftCache entries would get automatically deleted when the class loader was garbage collected, but we now handle that directly by monitoring the class loader reference in the cache key. ====================================================================== Name: nl37777 Date: 03/04/2004 The bug fix described above had to be backed out because it caused regression 4681727. A new fix has been implemented that subclasses WeakReference for references to class loaders, which leads to a much simpler fix. In particular, the cache is implemented as a SoftCache again. ======================================================================

SUGGESTED FIX Switch loaderRef to be a WeakReference instead of a SoftReference.