【问题标题】:Hibernate Caching Problem休眠缓存问题
【发布时间】:2011-11-18 07:12:15
【问题描述】:

我一直在处理我的应用程序中的内存问题,并相信我终于通过使用 Yourkit 进行分析来解决这个问题 - 我在会话中缓存用户,但每个被缓存的 User 是 2MB,这会创建一个整体用户登录并保存会话时的大量内存:

Users are taking up 50% of RAM

Each User Object is 2MB, some taking 8MB

当我展开每个类时,似乎所有内存都被与authorities 的关联所占用,它定义了用户的角​​色:Expanded Class In Yourkit

以下是相关类的 Hibernate XML:

用户:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.pps.domain" default-lazy="false">

    <class name="User" table="pps_users">
        <cache usage="read-write"/>
        <comment>User</comment>

        <id name="id" type="long">
            <generator class="native">
            </generator>
        </id>
 <set name="authorities" inverse="true" table="pps_user_roles" lazy="true">
            <cache usage="read-write"/>
            <comment>User - Roles Associations</comment>
            <key column="user_id"/>
            <many-to-many column="role_id" class="com.pps.domain.Role"/>
        </set>
    </class>

</hibernate-mapping>

角色:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.pps.domain" default-lazy="false">

    <class name="Role" table="pps_roles" lazy="true">
        <cache usage="read-write"/>
        <comment>Role</comment>

        <id name="id" type="long">
            <generator class="native">
            </generator>
        </id>

        <property name="description"/>
        <property name="authority"/>

        <set name="users" table="pps_user_roles" lazy="false">
            <cache usage="read-write"/>            
            <comment>User - Roles Associations</comment>
            <key column="role_id"/>
            <many-to-many column="user_id" class="com.pps.domain.User"/>
        </set>
    </class>


</hibernate-mapping>

我认为,由于 Roles 表正在缓存用户(系统中有超过 10,000 个用户),因此导致 User 类膨胀,但删除 &lt;cache usage="read-write"/&gt; 并没有帮助。我对Hibernate不太了解,所以我不确定我哪里出错了。有什么建议吗?

注意:该项目位于 Grails 1.3.7 中,如果有帮助,我正在使用(已弃用)acegi 插件。

编辑:

我删除了authorities 集合和Role 中对cache 的引用。物体实际上变大了。此外,在 YourKit 中,每个用户的对象计数为 10,900,这在系统中的少数实际用户之内,因此它仍然必须以某种方式缓存它们。我需要这不是真的!

【问题讨论】:

  • 如果你只是从两个类中删除所有缓存,只是为了看看你的内存是如何受到影响的,会发生什么?
  • @Mac - 不知何故,每个加载的实例内存会跳到 10MB,这没有任何意义。

标签: hibernate caching memory grails spring-security


【解决方案1】:

不要关闭缓存,而是将缓存配置为允许更少的对象并且不会永远缓存它们,这听起来像是它可能正在做的事情。有关 Hibernate 如何使用缓存以及如何命名缓存区域的详细信息,请参阅"The Second Level Cache",以便您知道如何更改正确的缓存设置。

编辑:再想一想,根据您的 cmets,Hibernate 缓存不是您的问题。您所描述的不是缓存在 Hibernate 中的工作方式。缓存角色这一事实并不意味着也缓存了所有用户。每种类型的对象都是独立缓存的。除了 Hibernate 的二级缓存之外,您还需要查看其他地方。加载角色会导致 10k 用户加载这一事实可能就是问题所在。你不想要那个。你可能想看看"extra-lazy" collection fetching。还要检查 Yourkit 以查看究竟是什么持有对这些东西的引用(如果有的话)。

【讨论】:

  • 看起来我的Role 类仍在缓存具有该角色的所有用户,我根本不希望它这样做。所有用户基本上都是“普通”角色,因此这会产生一个有 10,000 个用户对象连接到它的角色。我想如果我为此删除了缓存行,它根本不会缓存,但我没有看到这种情况发生。你有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 2016-08-13
  • 2012-04-29
  • 2015-01-05
  • 2017-01-16
相关资源
最近更新 更多