java 堆转储中有大量的休眠查询,我该如何限制?

bkkx9g8r  于 2023-03-11  发布在  Java
关注(0)|答案(2)|浏览(174)

我正在处理一个大型应用程序,它有数百个休眠实体和EAGER关联,当我启动这个应用程序时,内存消耗非常高(超过1GB)。
在刚启动后查看应用程序的JVM堆转储,我分析并了解到大部分内存被char[]占用,这些char[]具有来自应用程序不同实体的不同SELECT语句。
我假设这个SELECT由Hibernate的查询计划缓存生成。
我希望限制开发环境中此缓存的大小。我尝试使用一些属性限制大小:

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

但是在内存消耗方面没有区别。
我应该做什么来限制Hibernate查询该高速缓存?
我使用的是Hibernate 5.0.10。

pw136qt2

pw136qt21#

确实有很多问题与“查询计划缓存内存使用”有关。(1234)。但作为一个解决方案,现在我们可以设置一些设置,其中之一- * hib.query.plan_cache_max_size*。奇怪的是,它没有帮助,在我的情况下,它工作。也许问题隐藏在其他地方。
如果您有一个堆转储,尝试使用Memory Analyzer(MAT)检查您的假设,运行以下OQL查询(如果您还没有这样做):

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

它会给予你一个额外的信息。
以防万一。您是否尝试更改所有这些设置的值?

"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"
oug3syen

oug3syen2#

“hibernate.query.plan_cache_max_size”对我很有效。通过尝试避免在查询中将动态参数发送到“IN”条件,可以从实现中减少这个休眠查询缓存。

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

每次调用生成上述带有特定数量参数的示例查询的休眠查询,都会在该高速缓存计划中存储1行。
相反,可以通过设置属性将hib配置为以2的幂发送固定数量的参数

hibernate.query.in_clause_parameter_padding: true

例如,如果有5、6、7或8个参数,则将使用in ($param1,$param2,$param3,$param4,$param5,$param6,$param7,$param8),在仅有5个参数的情况下,则最后一个参数重复4次。
通过这种方式,休眠缓存中的查询计划数量大大减少。除了减少这些非常大的查询所需的内存量,还应该提高命中率。如果您的RDBMS具有数据库SQL查询计划缓存,那么这种好处也会扩展到数据库SQL查询计划缓存。
参考:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#configurations-query

相关问题