Konstantin, On 5/1/12 11:04 AM, Christopher Schultz wrote: > On 4/28/12 8:58 PM, Konstantin Kolinko wrote: >> >> I am OK with your proposal, but I do not expect much savings from >> getting rid of those duplicates. Does YouKit show some estimates? > > It did, but I closed it long ago so I'll have to re-check. IIRC, it was > a couple of MiB. Of course, it's not feasible to check 100% of them > because there were so many copies. I can hack a bit at Tomcat and see > what percentage of them disappear. Then I'll know whether such a change > in Tomcat actually has a meaningful impact.
YourKit shows 1123 copies of "java.lang.String" for a "waste" of 89760
bytes. Sure, that's nothing. But, I don't have much in the way of stuff
loaded. With multiple webapps, hosts, etc. I suspect that numebr will
just go up.
Let's see how much can be attributed to Tomcat's MBeans...
I can see that the following fields retain references to duplicate
"java.lang.String" strings:
org.apache.tomcat.util.modeler.AttributeInfo.type
org.apache.tomcat.util.modeler.OperationInfo.type
javax.management.MBeanOperationInfo.type
javax.management.MBeanAttributeInfo.attributeType
(I'll have to look at where we create those last two to see if we can
pass-in a shared reference to "java.lang.String").
There are 883 instances of AttributeInfo and I assume that all of them
are using duplicate strings.
o.a.t.u.m.MbeansDescriotorsIntrospectionSource.createManagedBean creates
new AttributeInfo objects in this code (trunk, starting at line 302):
Enumeration<String> en = attMap.keys();
while( en.hasMoreElements() ) {
String name = en.nextElement();
AttributeInfo ai=new AttributeInfo();
ai.setName( name );
Method gm = getAttMap.get(name);
if( gm!=null ) {
//ai.setGetMethodObj( gm );
ai.setGetMethod( gm.getName());
Class<?> t=gm.getReturnType();
if( t!=null )
ai.setType( t.getName() );
}
Method sm = setAttMap.get(name);
if( sm!=null ) {
//ai.setSetMethodObj(sm);
Class<?> t = sm.getParameterTypes()[0];
if( t!=null )
ai.setType( t.getName());
ai.setSetMethod( sm.getName());
}
ai.setDescription("Introspected attribute " + name);
if( log.isDebugEnabled()) log.debug("Introspected
attribute " +
name + " " + gm + " " + sm);
if( gm==null )
ai.setReadable(false);
if( sm==null )
ai.setWriteable(false);
if( sm!=null || gm!=null )
mbean.addAttribute(ai);
}
In either case, the "type" of the AttributeInfo is coming from
Class.getName, which I would have expected to be interned. The Method
values in attMap come directly from Class.getMethods() so it should all
be coming from the JVM's RTTI.
I checked ran a very simple test and found that Class.getMethods returns
a new set of objects every time it is called (at least in my
environment: MacOSX/Java HotSpot(TM) 64-Bit Server VM (build
20.6-b01-415, mixed mode)). I must admit I'm a little surprised that
Class.getMethods doesn't cache the Method objects it creates.
Anyhow, the Class objects that are used for Method.getReturnType *are*
shared, and the return values from those are also shared (so,
String.class.getMethod("compareTo", {String.class}) returns parameter
and return types that are == to each other, and calling Class.getName on
each of those returns String values that are == to each other).
I'm going to keep looking.
-chris
signature.asc
Description: OpenPGP digital signature
