Reputation: 4094
I have a webapp that combines Spring + Hibernate. I deploy this locally in a Tomcat Server and I get memory consumptions of around 150-200 Mb which to my knowledge is not that high at all. But apparently in production deployment, which works over WebSphere, I am getting 500Mb of memory usage, and a very high frequency of garbage collection.
At first I blamed Hibernate for the problem (as seen in this other question) but now I am lost as to what might be causing this apparent high usage.
I tried profiling my app using MAT and these are my histogram results:
I haven't got much experience at profiling memory and most of the time I feel as if I was looking at the car's engine after a failure, but it seems to me that the char[] references are related to spring's internal "database" of beans. I use annotation based configuration for spring's mvc components and transactions:
<tx:annotation-driven />
<context:annotation-config />
Do you find any of these values to be exceptionally high? Can you help me tracing the problem up?
PS. this is my dominator for a heap dump nearer to a full heap
Upvotes: 0
Views: 5183
Reputation: 4094
I have found that I do have a high memory consumption for each rendered page, and have pinpointed the issue to Apache Tiles. If I use Tiles, each page load burdens the heap with up to 30 mb of memory usage, which does feel like a lot. Disabling it causes almost no memory consumption.
Debugging the controller methods shows that within the method itself almost no memory consumption is done, but it is upon returning control to the viewresolver (i.e. after the controller method ends) when the 30mb memory usage fires.
The problem now is, how to reduce this memory usage??
Upvotes: 0
Reputation: 9480
You do realise that (unless you're using Liberty Profile) WebSphere piles a huge number of additional jar files into your classpath compared to Tomcat? Therefore, a significantly larger memory footprint is absolutely to be expected under WebSphere.
Excessive garbage collection implies that you have not allocated enough memory to your application JVM. Give it significantly more (2 gig for instance) and watch the runtime memory usage graph via JConsole or a similar tool. Watch what memory consumption it reaches before a more relaxed garbage collection and use that to educate yourself on how much the JVM does really need.
Note that if after each garbage collection, the graph does not return to a safe baseline, but instead only reduces partially, then you probably have a memory leak.
Upvotes: 1
Reputation: 4341
Both your problems are (usually) normal.
The garbage collector running often indicates you have a lot of processing going on, especially the kind that creates lots of objects (like jdbc). Unless your server becomes non-responsive during garbage collection, it's nothing to worry about. If it's not returning to the baseline memory (the bottom of the sawtooth memory graph) after garbage collection, you might have a leak.
High memory usage is also normal, especially if you've given more memory to the production JVM than your local one. Compare your startup parameters and make sure they are the same before trying to compare their performance results.
[i know this is not really an answer, but it's too long to fit in comments]
Upvotes: 2