在堆转储中,Hibernate查询的作用

8
我正在使用JProfiler分析我的应用程序以解决高CPU使用率的问题。在用户登录时,CPU使用率是100%(在服务器上)。所以我开始了对我的应用程序进行剖析。
我在堆转储中找到了以下查询字符串。不仅这4个查询,转储中有数百个类似的查询。
java.lang.String (0x3262b1) ["/* load com.v4common.shared.beans.transaction.ControlTransaction */ select controltra0_.id as id47_48_, controltra0_.form_transaction_id as form2_47_48_, controltra0_.string_value as string3_47_48_, c"]     129 kB (0 %)
java.lang.String (0x310b2f) ["/* load com.v4common.shared.beans.transaction.ReportTransaction */ select reporttran0_.id as id158_45_, reporttran0_.report_id as report2_158_45_, reporttran0_.norm_id as norm3_158_45_, reporttran0_.d"]     124 kB (0 %)
java.lang.String (0x312222) ["/* load com.v4common.shared.beans.transaction.ReportItemTransaction */ select reportitem0_.id as id160_41_, reportitem0_.report_structure as report2_160_41_, reportitem0_.grid_row_criteria as grid3_16"]     110 kB (0 %)
java.lang.String (0x30c104) ["/* load com.v4common.shared.beans.Reports.EsenderCSReport */ select esendercsr0_.id as id117_36_, esendercsr0_.name as name117_36_, esendercsr0_.report_type as report3_117_36_, esendercsr0_.is_show_pr"]     94,248 bytes (0 %)
java.lang.String (0x30d1dc) ["/* load com.v4common.shared.beans.Reports.ReportStructure */ select reportstru0_.id as id120_35_, reportstru0_.name as name120_35_, reportstru0_.xml as xml120_35_, reportstru0_.esender_format as esend"]     90,736 bytes (0 %)

我只是登入系统,完全没有操作豆子的动作,但我却可以在dumps中看到它们。

有任何想法为什么这些字符串会在dump中出现?

甚至这行代码是什么意思呢?


1
据我所知,这是由于 Hibernate 查询缓存引起的,但我不知道如何使 Hibernate 不存储这些查询。 - Luiggi Mendoza
1
你确定应用程序部署时不加载初始数据吗? - Luiggi Mendoza
1
除非我们明确设置,否则Hibernate不会缓存查询。我强烈怀疑上次调用中的对象未被垃圾回收。 - kosa
1
@Nambari,我已经尝试禁用此功能,但也没有起作用... - Luiggi Mendoza
这些查询不能对高CPU使用率负责,必须是其他原因。最坏的情况是它们会消耗大量内存但不会占用CPU,但内存消耗也不应该成为问题。尝试使用与JVM一起安装的VisualVM来分析CPU使用情况,这是一个非常用户友好的工具http://visualvm.java.net/。 - Angular University
显示剩余6条评论
2个回答

5

这是正常的,这些是在服务器启动时准备的Hibernate预定义查询。

ControlTransaction类为例。Hibernate已经知道可能需要按ID选择实体、删除实体等操作。

因此,它预先生成一系列SQL准备好的语句来执行这些操作。每个查询开头的注释说明了为什么要生成它们。

例如,这个查询被生成用于通过ID加载一个ControlTransaction:

/* load com.v4common.shared.beans.transaction.ControlTransaction */ 
select controltra0_.id as id47_48_, controltra0_.form_transaction_id as form2_47_48_, controltra0_.string_value as string3_47_48_, c 

one-to-manyone-to-one 注释开头的查询,用于惰性加载等。在 JPQL/HQL 中命名的查询也会在服务器启动时编译为 SQL 查询,并且注释标识了产生 SQL 查询的命名查询。

每个实体将根据使用的映射注释产生若干此类查询。

因此,这些查询在用户首次登录时存在堆中是正常的。


0
你的实体类中是否有使用 @NamedQueries(或 @NamedQuery)这些查询语句呢?
在服务器启动时,Hibernate 可能会将命名查询加载到其缓存中。它们肯定会在启动时被解析以检查语法等问题。

不,我没有任何查询。我正在使用Criteria API。 - Suresh Atta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接