我正在用最新版本的Spring Boot编程一个应用程序.最近我的垃圾堆越来越大,无法回收.使用Eclipse MAT对堆进行的分析表明,在运行应用程序的一小时内,堆增长到630MB,Hibernate的SessionFact或yImpl使用了整个堆的75%以上.

在此处输入图像描述

Is正在查询计划缓存周围寻找可能的源,但我只找到了this个,但没有找到.属性设置如下:

spring.jpa.properties.hibernate.query.plan_cache_max_soft_references=1024
spring.jpa.properties.hibernate.query.plan_cache_max_strong_references=64

数据库查询都是由Spring的Query magic生成的,使用in this documentation这样的存储库接口.使用这种技术可以生成大约20个不同的查询.没有使用其他本机SQL或HQL.

@Transactional
public interface TrendingTopicReposit或y extends JpaReposit或y<TrendingTopic, Integer> {
    List<TrendingTopic> findByNameAndSource(String name, String source);
    List<TrendingTopic> findByDateBetween(Date dateStart, Date dateEnd);
    Long countByDateBetweenAndName(Date dateStart, Date dateEnd, String name);
}

List<SomeObject> findByNameAndUrlIn(String name, Collection<String> urls);

as example f或 IN usage.

问题是:为什么查询计划缓存不断增长(它没有停止,它以一个完整的堆结束),以及如何防止这种情况?有没有人遇到过类似的问题?

版本:

  • 弹簧靴1.2.5
  • 冬眠4.3.10

推荐答案

我也谈到了这个问题.它基本上可以归结为在in子句中有数量可变的值,并且Hibernate试图缓存这些查询计划.

关于这个话题,有两篇很棒的博客文章.

在带有in子句查询的项目中使用Hibernate 4.2和MySQL

Hibernate缓存这些解析的HQL查询.尤其是冬眠

对于每一个不同的查询,这些缓存都会增长.所以这个查询有6000个

in子句查询扩展到

想象一下,in子句参数的数量有4000种不同的变化

这会一直持续到查询参数中出现所有不同的变化

避免in子句是一种 Select ,也可以使用固定集合

有关配置查询计划缓存最大大小的信息,请参阅属性

second(也参考了第一个):

Hibernate在内部使用cache映射HQL语句(如下所示)

因此,缓存抖动是在

由于hibernate中存在一些模糊的bug,所以在某些情况下

第二个问题在于hibernate处理查询的方式

那么,你是如何发现自己有这个问题的呢?你可以写一些

就性能影响而言,很难说这取决于什么

Postgresql相关问答推荐

"错误:无法创建用户:错误:关系\users\违反了非空约束

使用pg_repack从PostgreSQL中的表中删除OID

在插入时创建一个触发器,在PostgreSQL中的另一个表上创建另一个触发器

具有有限字母表的自定义字符串类型

是否可以在 postgres jsonb 列中的列表上创建索引

PostgreSQL pg_dump 创建 sql 脚本,但它不是 sql 脚本:有没有办法让 pg_dump 创建标准的 sql 脚本?

Postgresql如何从jsonB列的数组中的多个json中 Select 一个值

如何包装 record_out() 函数?

Postgres 根据自己的估计 Select 一个更费时的查询计划

postgresql查询中的正则表达式不区分大小写

PostgreSQL:是否可以将枚举转换为整数?

Rails 迁移:PostgreSQL 上的 Bigint 似乎失败了?

如何将1 天 01:30:00等间隔转换为25:30:00?

我不明白 postgresql 的 nextval() 是如何工作的,有人可以解释一下吗?

PostgreSQL:使用 psql 命令行实用程序时 Windows 上的编码问题

获取 psycopg2 count(*) 结果数

获取json列键为空的记录

如何在 postgresql 交叉表中用零替换空值

PostgreSQL 使用 UUID 与文本作为主键

PostgreSQL 9 在 Windows 上安装:Unable to write inside TEMP environment path.