struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Graham" <dgraham1...@hotmail.com>
Subject RE: Tiles excessive memory usage
Date Tue, 11 Mar 2003 20:53:46 GMT
If your estimates are accurate, we definitely need to rethink the Tiles 
implementation.  The CPU needed to do hash lookups is marginal and the 
apparent amount of memory needed outweighs avoiding hash lookups.

David



>From: Christophe Warland <christophe.warland@s1.com>
>Reply-To: "Struts Developers List" <struts-dev@jakarta.apache.org>
>To: 'Cedric Dumoulin' <cedric@apache.org>
>CC: "'struts-dev@jakarta.apache.org'" <struts-dev@jakarta.apache.org>
>Subject: RE: Tiles excessive memory usage
>Date: Tue, 11 Mar 2003 15:23:50 -0500
>
>You speak words of wisdom when you say that, in software development, there
>must often be a trade-off between CPU and memory usage. You are also right
>when you say that attributes are shared between the definitions; they are
>Java Strings after all. But the actual problem comes from the fact that 
>each
>definition has to create a specific HashMap$Entry object to store every
>key/value pair it inherits. And this can be prohibitive in large
>developments. This email explains how much memory you are trading in for 
>the
>couple of hundreds CPU cycles that would have been needed to process 
>chained
>Map.get(key) calls.
>
>I can unfortunately not share my source code with you. But suffices it to
>say that our application uses a fair number of component definitions and
>attributes (668 and 7037 respectively).
>
>With regards to the methodology used, simply start your JVM with "java
>-Xrunhprof:heap=sites ..." and look at the self-explanatory results in
>java.hprof.txt. I can also send you, Cedric, our detailed analysis under
>private email if you agree not to distribute it.
>
>Alternatively, you can also follow me through this enlightening theorical
>discussion. (The stats gurus amongst you are welcome to step in and correct
>me; from here on, I am only trying to show off and look smart :)
>
>As our example showed, just for one attribute, we ended up with 668 entries
>instead of one. For all the attributes in our system, we can use the
>following model:
>
>   if 'n' is the number of Component Definitions,
>      'K' is the total number of all the attributes, and
>      'd' the average depth of inheritance,
>
>   let's further call 'm' the average number of inherited attributes per
>Component Definition, with m being conceptually equivallent to (K/n)*d,
>
>   then we end up with instantiating (n*m)^d HashMap$Entry objects instead 
>of
>only 'K'.
>
>That is (n*m)^d instead of n*m/d. Exponential square instead of linear!
>
>To put that in perspective, our production app yields the following values:
>   n = 668
>   K = 7037
>   d = 1.57
>   m = 16.5
>And we get (668*16.5)^1.57 = 2,219,978 HashMap entries instead of the more
>intuitive 7,037 (= K). Since, one HashMap entry takes 24 bytes in memory,
>this represents my loss of 50 MB (see previous email).
>*Had* we developped an application with the same amount of Component
>Definitions and attributes but with a higher average depth of inheritance,
>for example d=2 instead of d=1.57, this model shows that we would have
>needed 4.5 GB of RAM just to load Tiles.
>This number looks ridiculously high, so my mathematical model is probably
>wrong. However, keep in mind that our app does need an extra 50 MB of RAM
>just to load 7037 attributes, which is ridiculously high too. So this
>exponential equation might not be too far from the truth.
>
>The bottom line is, Tiles does not scale for us. YMMV. We found a fix that
>works for us and we wanted you to be aware of it. Feel free to use it or
>drop it. And again, keep in mind that our analysis is based on Tiles
>2001-09-10, so this misbehavior might not be present in the latest Struts
>1.1 RC#.
>
>Back to your email, Cedric, it is also very much possible that we misuse
>Tiles. You say that we could "avoid the map creation in the contexts when 
>no
>locale attributes are set." Could you elaborate a little? Thanks.
>
>Best Regards,
>
>-- Christophe
>
>
>
>-----Original Message-----
>From: Cedric Dumoulin [mailto:cedric@apache.org]
>Sent: Tuesday, March 11, 2003 11:34 AM
>To: Christophe Warland
>Cc: 'struts-dev@jakarta.apache.org'
>Subject: Re: Tiles excessive memory usage
>
>
>
>Hi Christophe,
>
>     When you develop a software, you often need to choose between
>simplicity, CPU consumption and memory consumption
>   In the case of the ComponentContext implementation, and the
>inheritance mechanism, I have chosen the simplicity and the CPU
>consumption.
>   Furthermore,  while developping the ComponentContext (tile context)
>and the inheritance mechanism, I have tried to let the class
>ComponentContext independent from the ComponentDefinition class and its
>implementation.
>   So, the implementation of ComponentContext create a new Hashmap
>initialized from the definition hashmap. Also, the definition
>inheritance is resolved in a way where each definition has its own
>hashmap referencing all the attributes visible by the definition. Note
>that the attributes themselves are shared between all definitions, they
>aren't copied.
>   With this implementation, the access time to an attribute is constant.
>There is no need to check several hashmap. The drawback is the memory
>consumed. This is generally not really a problem on modern servers. The
>memory size is relatively constant because the hashmaps don't grow
>during the application life, they are initialized at startup only.
>
>   Nevertheless, it is certainly possible to find a better compromise
>between the CPU memory consumption and the space memory consumption. For
>example, it is possible to avoid the map creation in the contexts when
>no "locale" attributes are set. Also, it is possible to control the
>definition map sizes, which is not modified once the definition
>inheritances are resolved.
>
>   Maybe you can share with us your application used to do the benchmark
>(with all business stuff removed), and also the methodology used.
>
>   Cedric
>
>P.S.:   Je vois que avec le temps tu n'as rien perdu de ton esprit
>critique ;-).
>
>Christophe Warland wrote:
>
> > At my company, we have been recently forced to patch Tiles to solve
> > some major memory problems where Tiles was eating a lot of memory for
> > no apparent reasons. We wish to share our findings with you. And we
> > will be happy to send our code change to Cedric if he wishes so.
> >
> > Here are some quick numbers about our J2EE runtime after complete
> > bootup (appserver and EAR file are up, deployed and ready to serve
> > HTTP requests):
> >  - With original Tiles code: 79 MB of RAM is used
> >  - After our custom code change: 28 MB of RAM is used
> >
> > Note that the Tiles version that we use is an old one (our source zip
> > shows 09/10/2001). However, a quick analysis of the more recent Tiles
> > source found in Struts 1.1 RC1 shows that most the code where the
> > defect lies is still in there. But we haven't actually been able to
> > confirm the problem at runtime since our app is not compatible with
> > the latest Struts and Tiles development.
> >
> > Here are a few excerpt of our internal analysis so that you can
> > understand the issue.
> >
> > --
> >
> > Our application does not actually make use of the Tiles template
> > mechanism but instead builds on top of Tiles' i18n concept to offer
> > localized Web pages based on an individual's language, country,
> > personality and channel. We make extensive use of Tiles Component
> > definitions and inheritance in XML files, and 667 out of the 668
> > definitions used by our app inherit from another one.
> >
> > With the help of a Java profiler, we showed that 64% of the 79 MB of
> > memory was used by HashMap entries created by Tiles.  This corresponds
> > to 50.5 MB of RAM. After close investigation, it turns out that the
> > very useful Tiles' component inheritance has been mis-implemented.
> >
> > Our application has only one definition that doesn't extend another
> > one: the root "pageDefinition", which contains common information such
> > as "pageCopyrightLink" for example. Other Component Definitions that
> > extend "pageDefinition", such as "disbursementCB", do not need to
> > repeat this information. When queried for the "pageCopyrightLink"
> > value, the "disbursementCB" component will delegate the processing to
> > its parent component, in this case "pageDefinition".
> >
> > Unfortunately, this handy conceptual delegation is actually not
> > implemented in a similar way in the Tiles source code.
> >
> > In our example, when the "disbursementCB" component is instantiated in
> > memory, the Tiles source code does not pass it a reference to the
> > parent "pageDefiniton" component. Instead, Tiles forces the new
> > "disbursementCB" component to make a deep copy of all values defined
> > in its parent(s). This means that, ultimately, our application ends up
> > with 668 copies of the "pageCopyrightLink" value in memory, instead of
> > one.
> >
> > After modification of the Tiles source code so that true delegation is
> > actually happening in memory at runtime, new heap allocation
> > statistics showed that the problem with excessive usage of
> > HashMap$Entry has been completely solved. The most in-use object in
> > the JVM is now of the type "[C", a common and normal trend in typical
> > Java applications.
> >
> > The total amount of memory was also down to 28 MB. This is a pleasant
> > 51 MB gain over the previous result.
> > --
> >
> > Finally, without being too demanding, we would appreciate if a patched
> > version of Tiles could be made available for for both the upcoming
> > Struts 1.1 release and the current stabe Strust 1.0.2 one.
> >
> >
> > Best Regards,
> >
> >
> > Christophe Warland
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: struts-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: struts-dev-help@jakarta.apache.org


_________________________________________________________________
The new MSN 8: smart spam protection and 2 months FREE*  
http://join.msn.com/?page=features/junkmail


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-dev-help@jakarta.apache.org


Mime
View raw message