jpa hibernate中扫描太多实体时,glassfish启动很慢或内存泄漏

Posted

技术标签:

【中文标题】jpa hibernate中扫描太多实体时,glassfish启动很慢或内存泄漏【英文标题】:When scanning too many entity in jpa hibernate, glassfish startup very slow or memorry leak 【发布时间】:2016-12-29 05:53:48 【问题描述】:

我正在使用 JavaEE7,hibernate-jpa2.1 我的项目有太多实体(大约 2000 个实体) 如果它只有 100 个对象实体,它启动正常。 但是现在我已经添加了我所有的业务实体类(2000)并且我得到了一个 pergem 空间错误。

 2016-12-29T11:40:36.903+0700|Severe: Exception in thread "DynamicReloader"
    2016-12-29T11:40:36.904+0700|Severe: java.lang.OutOfMemoryError: GC overhead limit exceeded
    2016-12-29T11:40:37.899+0700|Severe: Exception in thread "AutoDeployer"
    2016-12-29T11:40:37.900+0700|Severe: java.lang.OutOfMemoryError: GC overhead limit exceeded

我已经改进了 jvm 内存参数,但现在我的应用程序在启动过程中非常慢。 那么,我会知道是否有一些选项可以更快地加载这些实体? 提前致谢

这是示例实体

@Entity
@Table(name = "TBL_USER")
@NamedQueries(
        @NamedQuery(name = "TblUserO.findAll", query = "SELECT t FROM TblUserO t")
)
public class TblUserO implements Serializable 
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "USER_ID", unique = true, nullable = false, precision = 11)
    private Long userId;

persistence.xml

     <persistence-unit name="c1spostgre1" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/__PSG1</jta-data-source>
        <!-- Named JPQL queries per entity, but any other organization is possible -->
        <properties>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
            <!-- <property name="hibernate.archive.autodetection" value="class" /> -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL92Dialect" />
            <property name="hibernate.jdbc.batch_size" value="20" />
            <property name="hibernate.order_updates" value="true"/>
            <property name="hibernate.order_inserts" value="true"/>
        </properties>
    </persistence-unit>
    <persistence-unit name="c1spostgre2" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/__PSG2</jta-data-source>
        <properties>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
            <!-- <property name="hibernate.archive.autodetection" value="class" /> -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL92Dialect" />
            <property name="hibernate.jdbc.batch_size" value="20" />
            <property name="hibernate.order_updates" value="true"/>
            <property name="hibernate.order_inserts" value="true"/>
        </properties>
    </persistence-unit>

【问题讨论】:

【参考方案1】:

您已经增加了足够的堆内存(不是 permgen),以便您的应用现在可以启动,但是由于需要将大量内容加载到内存中,您几乎可以肯定在加载所有这些内容时会进行大量垃圾收集,这将导致放缓。听起来您需要对应用进行广泛的性能调整,但这远远超出了 *** 问题的范围。

【讨论】:

【参考方案2】:

您的应用程序在启动时似乎从数据库中加载了太多数据。我的猜测是额外的实体有太多急切的关系,你的应用程序加载了太多不必要的数据来完成它需要做的事情。

我建议检查实体映射并将尽可能多的关系减少为惰性关系(尤其是 *ToMany 关系应该全部惰性获取,这是默认设置)。在搜索加载了哪些不必要的数据时,您可以打开 SQL 查询的日志记录以检测用于加载数据的 SQL 脚本。您的应用程序可能正在将某些表中的所有实体加载到内存中,并稍后过滤它们,这效率不高。

您应该重新考虑将过滤放入 JPQL 查询中。您还应该减少 findAll 查询的使用,或者至少在调用 getResultList() 之前使用 setMaxResult() 限制检索到的实体的数量。

【讨论】:

以上是关于jpa hibernate中扫描太多实体时,glassfish启动很慢或内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 JPA 2/Hibernate 中使用共享主键时实体需要可序列化?

在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)

JPA/Hibernate 无法创建名为 Order 的实体

如何在同一个数据库表上映射两个 JPA 或 Hibernate 实体

Cascade保存子实体失败了JPA(Spring数据+ Hibernate)?

JPA+Hibernate - 实体关系中的循环 - 级联策略