2011-09-15 93 views
1

我一直在处理我的应用程序中的内存问题,并相信我最终通过使用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> 

我想,因为角色表被缓存用户(并且系统中有超过10,000个用户)认为臃肿的User类是由此导致的,但删除了<cache usage="read-write"/>没有帮助。我对Hibernate不太了解,所以我不确定自己出错的地方。有什么建议么?

注意:该项目在Grails 1.3.7中,如果有帮助,我使用(不建议使用)acegi插件。

编辑:

我的设置以及在Roleauthorities同时取出引用cache。该对象实际上变大了。此外,在YourKit中,每个用户的对象数为10,900,这在系统中的实际用户数量内,因此它仍然必须以某种方式缓存它们。我需要这不是真的!

+0

如果您只是从两个类中删除所有缓存,会发生什么情况,以查看您的内存如何受到影响? – Mac

+0

@Mac - 不知何故,内存跳转到每个实例加载10MB,这是没有意义的。 – skaz

回答

1

不是关闭缓存,而是将缓存配置为允许更少的对象,并且不会永久缓存它们,这听起来就像它可能正在做的一样。有关Hibernate如何使用缓存以及如何命名缓存区域的详细信息,请参见"The Second Level Cache",以了解如何更改正确的缓存设置。

编辑:第二个想法,基于您的意见,Hibernate缓存不是你的问题。你所描述的不是缓存在Hibernate中的工作原理。角色被缓存的事实并不意味着所有的用户都被缓存了。每种类型的对象都被独立缓存。除了Hibernate的二级缓存之外,你还需要去看看。加载角色这一事实导致10k用户加载可能是问题。你不想那样。你可能想看看"extra-lazy" collection fetching。如果有的话,请检查Yourkit以查看究竟是什么引用了这些东西。

+0

它看起来像我的'角色'类仍然缓存所有用户与该角色,我不希望它做的。所有用户基本上都是“正常”角色,因此这会产生一个包含10,000个用户对象的角色。我想,如果我为此删除了缓存行,它根本不会缓存,但我没有看到发生这种情况。你有什么想法? – skaz

+1

@skaz:更新了我的答案 –