JDK-6595845 : Java 6 JavaWebstart increases footprint by factor 2
  • Type: Bug
  • Component: deploy
  • Sub-Component: webstart
  • Affected Version: 6u1
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-08-22
  • Updated: 2011-06-07
  • Resolved: 2011-06-07
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.
JDK 6 JDK 7 Other
6u10Fixed 7 b65Fixed OpenJDK6Resolved
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Customer reported that using JWS 6u1 increases footprint of their
application by factor 2. 

The application was only started up and some initial but identical 
functions were called.

Customer used the following setup:

Application AgreeBAP 3.2 (customer's application)
JRE 6u1

When using JWS 6u1 on JRE 6u1 (default) to load the application, we have the 
following Java objects' footprint:
       #instances    #bytes
 Total  1988354   107676864 

When using (as a diagnostic test) JWS 1.4.2_11 on JRE 6u1 to load the application, 
we have the following Java objects' footprint:
       #instances    #bytes
 Total   825587    51769992

Please note that in both cases JWS was running on JRE 6u1. So the only 
component that varied was JWS. Customer's application remained unchanged
as well.

Memory consumption of the application changed like follows:

< totalMemory=62316544bytes \= 59,430MB
< freeMemory=26646976bytes \= 25,413MB
---
> totalMemory=133234688bytes \= 127,062MB
> freeMemory=41470472bytes \= 39,549MB



Looking into histograms gives:

num   #instances    #bytes  class name                       num   #instances    #bytes  class name
--------------------------------------                       --------------------------------------
  1:    131730    13009576  [C                            |    1:    364708    40070096  [C
  2:     42319     4807904  <constMethodKlass>            |    2:    105221     9778616  [Ljava.util.HashMap$Entry
  3:      9150     3647584  [I                            |    3:    366263     8790312  java.lang.String
  4:     42319     3387056  <methodKlass>                 |    4:    318200     7636800  java.util.HashMap$Entry
  5:    134691     3232584  java.lang.String              |    5:      7434     5809336  [B
  6:     70516     2753528  <symbolKlass>                 |    6:     39657     4583280  <constMethodKlass>
  7:      5273     2592840  [B                            |    7:    105166     4206640  java.util.HashMap
  8:      4117     2293992  <constantPoolKlass>           |    8:     39657     3173696  <methodKlass>
  9:      4117     1985904  <instanceKlassKlass>          |    9:    109248     2701384  [I
 10:      3496     1294448  <constantPoolCacheKlass>      |   10:     69414     2699248  <symbolKlass>
 11:     50941     1222584  java.util.HashMap$Entry       |   11:      3861     2218800  <constantPoolKlass>
 12:     23546     1075024  [Ljava.util.HashMap$Entry;    |   12:      3861     1885528  <instanceKlassKlass>
 13:     39960      959040  java.util.Hashtable$Entry     |   13:    104183     1666928  java.util.jar.Attributes$Name
 14:     23519      940760  java.util.HashMap             |   14:     98296     1572736  java.util.jar.Attributes
 15:     12709      622184  [Ljava.lang.Object;           |   15:      3272     1230960  <constantPoolCacheKlass>
 16:      5379      511920  [S                            |   16:     15275     1222000  java.lang.reflect.Method
 17:      4661      447456  java.lang.Class               |   17:     15480      710176  [Ljava.lang.Object;
 18:      1392      389232  [Ljava.util.Hashtable$Entry;  |   18:      5056      498856  [S
 19:     11216      358912  java.lang.ref.SoftReference   |   19:      4369      419424  java.lang.Class
 20:      4221      337680  java.lang.reflect.Method      |   20:     10743      343776  java.lang.ref.SoftReference
 21:     20440      327040  java.util.jar.Attributes$Name |   21:      2895      324960  [Ljava.lang.String;
 22:      2676      317856  [Ljava.lang.String;           |   22:     12283      294792  java.lang.ref.WeakReference
 23:      7043      299472  [[I                           |   23:      6539      279400  [[I
 24:     12326      295824  java.lang.ref.WeakReference   |   24:      3782      242048  java.beans.PropertyDescriptor
 25:     18452      295232  java.util.jar.Attributes      |   25:     14509      232144  java.util.HashMap$EntrySet
 26:     18423      294768  java.util.HashMap$EntrySet    |   26:      7949      190776  java.util.LinkedList$Entry
 27:      3782      242048  java.beans.PropertyDescriptor |   27:      7778      186672  java.util.Hashtable$Entry
 28:       535      171200  <objArrayKlassKlass>          |   28:       499      159680  <objArrayKlassKlass>
[ ... ]

Total   825587    51769992                                |  Total  1988354   107676864 


So, we have a threefold incease of objects of type [C : this account for 25 MB increase alone.
  1:    131730    13009576  [C                          |    1:    364708    40070096  [C

 a nearly threefold increase for objects of java.lang.String :
  5:    134691     3232584  java.lang.String            |    3:    366263     8790312  java.lang.String

 a sixfold increase for objects of java.util.HashMap$Entry:
 11:     50941     1222584  java.util.HashMap$Entry     |    4:    318200     7636800  java.util.HashMap$Entry

 a fourfold increase in for objects of [Ljava.util.HashMap$Entry :
 12:     23546     1075024  [Ljava.util.HashMap$Entry;  |   2:    105221     9778616  [Ljava.util.HashMap$Entry

 however a nearly fivefold decrease for objects of java.util.Hashtable$Entry :
 13:     39960      959040  java.util.Hashtable$Entry     27:      7778      186672  java.util.Hashtable$Entry
Identical bahviour was confirmed for Java 6u2.

Comments
EVALUATION 6u4 thru 6u14 changes were included in JDK7 b65
30-12-2009

EVALUATION Changes reduce footprint for other webstart applications and applets too but not that dramatically. E.g. for bugster at login screen: 6u3 - 5.5Mb fixed 6u10 - 3.6Mb
11-02-2008

EVALUATION Further changes: 1) I've changed J2SE code (ZipFile) a bit to release unneeded buffers. Measurement shown that there were 6M in these buffers for this particular application. 2) Most of CacheEntry content is now softly referenced. This helps to release memory if these entries are not really used. 3) Reworked memory part of cache. It did not seem to work well because only one reference was saved and resource was considered as unused as soon as it was released. This cause extra reloads and also together with my changes it made things fragile. (Because we may need to restore data after long idle time and if resource was considered unused it could have been removed). Moved memory related logic to separate class (MemoryCache), trying to create phantom reference every time new copy of resource is getting used and releasing resource only after reference counter gets to 0. Added yet another cleanup thread for this. 4) Replaced ImmutableManifest with transforming manifest to read only in place using reflection and Collections. This saves some memory but it has a drawback. Attempt to modify read-only Manifest will now throw UnsupportedOperationException. 5) Updated CachedJarFile14 similarly to CachedJarFile Test results are promising. Better footprint and performance than 1.4.2. Here are details: ------------- BAP 3.10-14 Heap b4GC afterGC -------------------------------------- 14211 on JRE 16004 28-32 21.7 16004 117-125 90.0 16010 103-106 14.7 2. Finding minimum heap amount ------------------------------------------------- Tests showed that the application starts fine with no noticeable performance impact with a max of 15MB. The application itself needs 14.7 MB. Download still works fine with a max of 10MB with no performance impact, but the application then fails to initialize. This shows that Web Start now needs less than 10 MB, while it used to require more than 90 MB before the optimizations, and still about 70 MB in the last tests. Performance: Web Start App download time [min:sec] Web Start 1.4.2_11 on JRE 1.6.0_04 max-heap=128M: 6:20 Web Start 1.6.0_04 on JRE 1.6.0_04 max-heap=128M: 6:07 Web Start 1.6.0_10 on JRE 1.6.0_10 max-heap=128M: 5:59 max-heap=75M: 6:02 max-heap=70M: 6:03 max-heap=65M: 6:01 max-heap=55M: 6:05 max-heap=45M: 6:03 max-heap=35M: 6:04 max-heap=25M: 6:04 max-heap=20M: 6:07 max-heap=15M: 6:06 max-heap=10M: 6:09
01-02-2008

EVALUATION For customer application memory consumption is as follows: BAP 3.10-14 b4GC afterGC ---------------------------------------------------------- Heap Perm Heap Perm ---------------------------------------------------------- 14211 on JRE 16004 28-30 15.4 21.6 15.0 16004 122-124 16.5 82.4 16.0 16010b411 114-132 16.4 110.3 16.0 Investigation shows that most of additional space is taken by CachedJarFile (in particular Manifest and signerMap). Experiments with replacing reference to ImmutableManifest with weak reference confirms this idea: 16010b411+deploy.jar 65-130 16.5 49.7 16.0 Memory consumption decreases from 110.3 to 49.7, i.e. by 60Mb. Difference between 6u10 and 6u4 seems to be explained by introduction of ImmutableManifests (see 6566201) that seems to mistakenly keep 2 copies of manifest (because ImmutableManifest constructor calls super(mf) that creates clone of manifest and this copy is never used). Given that 60Mb is needed for manifest objects, extra copy should cost about 30Mb and this is very close to observed difference between 6u4 and 6u10. Avoiding duplicate copies peak memory consumption should decrease (and it should have possitive impact on performance). From heap dump it seems that keeping weak references to signerMap may help to reduce footprint by another 20Mb. This has to be verified yet. Also, from code inspection it seems that we probably can keep immutable manifest as part of CacheEntry unless there is a reason to alter these manifests. And we probably do not need to clone signersMap too before creating immutable collection. The downside of it is that manifest and signers might need to be reconstructed if they will be needed later and this may have impact on performance.
16-01-2008