United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7064279 Introspector.getBeanInfo() should release some resources in timely manner
JDK-7064279 : Introspector.getBeanInfo() should release some resources in timely manner

Details
Type:
Bug
Submit Date:
2011-07-08
Status:
Closed
Updated Date:
2013-11-20
Project Name:
JDK
Resolved Date:
2011-12-14
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.beans
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u25
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Backport:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
A CU faces with memory leak. This seems to occur because Introspector.getBeanInfo()
does not release some resources.

CONFIGURATION:
JDK: 6u15(and later)/JDK7
OS : WindowsXP(SP3, Japanese)


INVESTIGATION:
The following source portion is extracted from JDK6u23.

The program accesses to AppContext at line#162.
If this access is the first time, AppContext.<clinit> starts to run.

---------------------------------------------------------------------------------------------
<j2se/src/share/classes/java/beans/Introspector.java>
 150     public static BeanInfo getBeanInfo(Class<?> beanClass)
 151         throws IntrospectionException
 152     {
 153         if (!ReflectUtil.isPackageAccessible(beanClass)) {
 154             return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
 155         }
 156         Map<Class<?>, BeanInfo> beanInfoCache;
 157         BeanInfo beanInfo;
 158         synchronized (BEANINFO_CACHE) {
 159             beanInfoCache = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
 160             if (beanInfoCache == null) {
 161                 beanInfoCache = new WeakHashMap<Class<?>, BeanInfo>();
 162                 AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
 163             }
 164             beanInfo = beanInfoCache.get(beanClass);
 165         }
 166         if (beanInfo == null) {
 167             beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo();
 168             synchronized (BEANINFO_CACHE) {
 169                 beanInfoCache.put(beanClass, beanInfo);
 170             }
 171         }
 172         return beanInfo;
 173     }
---------------------------------------------------------------------------------------------

In  AppContext.<clinit>, AppContext instance is created and the value of 
Thread.currentThread().getContextClassLoader() is set to the field of 
contextClassLoader at line#227.
The referent to the contextClassLoader never be broken.
That seems to result in memory leak.

---------------------------------------------------------------------------------------------
<j2se/src/share/classes/sun/awt/AppContext.java>
221     AppContext(ThreadGroup threadGroup) {
222         numAppContexts++;
223
224         this.threadGroup = threadGroup;
225         threadGroup2appContext.put(threadGroup, this);
226
227         this.contextClassLoader =
228             (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
229                     public Object run() {
230                         return Thread.currentThread().getContextClassLoader();
231                     }
232                 });
233     }
---------------------------------------------------------------------------------------------


SAMPLE PROGRAM:

A small program which simulates the above mentioned behavior.
Please unfoled the TP.zip and invoke "java Test" in jdk6ux.

If the referent is broken correctly, the message
"OK: MyClassLoader is not Reference."
appears and this is expected.

On tje other hands, in jdk6u15 and later,
"NG: MyClassLoader is Reference."
 will appear.
This shows that the referent still remains under the situation
when that should be broken.

In this test case, the impact is very small.
However, in actual applications like appli. servers, 
such small leak piles up for long application's run. 
That result in serious memory exhaustion.

Please see the comment section for a little bit more comment by the CU.

                                    

Comments
EVALUATION

See comments.
                                     
2011-07-13
Verified in JDK8b116
Windows 7 Pro x64
Windows XP x32

Test output:

cls.getClassLoader() = sun.misc.Launcher$AppClassLoader@15db9742
OK: MyClassLoader is not Reference
                                     
2013-11-20



Hardware and Software, Engineered to Work Together