Lots of hibernate queries in heap dump. How can I limit?

Viewed 4034

I'm dealing with a big application that have hundreds of hibernate entities and EAGER associations. When I start this application the memory consumption is very high (more than 1 GB).

Looking in the JVM heap dump of the application just after started, I analyzed and understood that the most of the memory is occupied by char[] with different SELECT statements from different entities of the application.

I suppose that this SELECTs are generated by the query plan cache of the Hibernate.

I would like to limit the size of this cache for the development environment. I tried to limit the size with some properties:

"hibernate.query.plan_cache_max_size", "16" //default is 2048
"hibernate.query.plan_parameter_metadata_max_size", "16" //default is 128

But there is no difference in the memory consumption.

What I'm supposed to do to limit the cache of Hibernate queries?

I'm using Hibernate 5.0.10.

2 Answers

There are really a lot of issues which were related with "Query Plan Cache Memory usage". (1, 2, 3, 4). But as a solution right now we can setup some settings, one of them - hibernate.query.plan_cache_max_size. It's weird, that it didn't help, in my case it worked. Perhaps the issue is hiding somewhere else.

If you have a heap dump, try to check your assumption by using Memory Analyzer (MAT), run this OQL query (if you haven't done it yet):

SELECT l.query.toString() FROM INSTANCEOF org.hibernate.engine.query.spi.QueryPlanCache$HQLQueryPlanKey l

It will give you an additional information.

And just in case. Did you try to change a value for all these settings?

"hibernate.cache.query_cache_factory"
"hibernate.query.plan_cache_max_size"
"hibernate.query.plan_cache_max_soft_references"
"hibernate.query.plan_cache_max_strong_references"
"hibernate.query.plan_parameter_metadata_max_size"

The "hibernate.query.plan_cache_max_size" works for me. This hibernate query cache can be reduced from the implementation by trying to avoid dynamic parameters sent to "IN" condition in the query.

SELECT * FROM TEST_TABLE WHERE A_COLUNN IN ($param1, $param2, ....)

Each call to the hibernate query which generated above sample query with a specific number of parameter would store 1 row in the cache plan. Try to use a fix number of parameters send to the query if possible.

Related