2013-09-22 66 views
1

我有JSF Web应用程序。我使用的是JSF 2.1.9,Hibernate 4.1.4,GlassFish 3.1.2,PrimeFaces 3.4.1。问题是,使用的堆大小缓慢增加,并在2-3天后达到最大堆大小。然后我必须重新启动GlassFish。使用的堆大小不断增加

堆转储:

在开始的时候,我点击应用中的所有网页和使用的堆大小为100 MB:

heapdumpbefore

一压脚提升1-2天,使用的堆大小提高到300 MB(在此期间,使用相同的网页):

heapdump after

我把小号堆中最常用的类的截图。

char[]类的实例,也有太多的SQL查询字符串这样的: heapdump char

也许没有只有一个问题,但我可能会开始从这一解决。在我的网页中,我通常从数据库中选择一些对象并进行渲染。这里有一些豆类: 图像(索引控制器):

@Named("indexController") 
@SessionScoped 
public class IndexController implements Serializable { 
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("imagePU"); 

    public List<Image> getImages() { 
     EntityManager em = emf.createEntityManager(); 
     List<Image> result; 
     try { 
      EntityTransaction entr = em.getTransaction(); 
      boolean committed = false; 
      entr.begin(); 
      try { 
       Query query = em.createQuery("SELECT i FROM Image i ORDER BY i.imageId DESC").setMaxResults(12); 
       result = query.getResultList(); 
       entr.commit(); 
       committed = true; 
      } finally { 
       if (!committed) { 
        entr.rollback(); 
       } 
      } 
     } finally { 
      em.close(); 
     } 
     return result; 
    } 
} 

标签图片:

@Named("galleryBean") 
@SessionScoped 
public class GalleryBean implements Serializable { 

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("imagePU"); 

    public List<TaggedImage> getTaggedImages() { 
     EntityManager em = emf.createEntityManager(); 
     List<TaggedImage> result; 
     try { 
      EntityTransaction entr = em.getTransaction(); 
      boolean committed = false; 
      entr.begin(); 
      try { 
       Query query = em.createQuery("SELECT ti FROM TaggedImage ti GROUP BY ti.tag ORDER BY ti.taggedImagesId DESC"); 
       result = query.getResultList(); 
       entr.commit(); 
       committed = true; 
      } finally { 
       if (!committed) { 
        entr.rollback(); 
       } 
      } 
     } finally { 
      em.close(); 
     } 
     return result; 
    } 
} 

顺便说一句,我不应该执行干将业务逻辑,但我认为这不是主要我的问题的原因。我需要帮助和一些建议。如果需要,我可以提供更多信息。

感谢您的帮助。

回答

0

我曾经有过类似JSF页面的问题,经过大量研究证明问题是JSF在会话中保留的视图数量。不知道这是你的情况的问题,但看看this来配置视图的数量。希望这可以帮助。

+0

会话超时是5分钟。 5分钟后,这些都必须从堆中释放出来吗?我正在测试这个应用程序,只有1个活跃用户 – Deniz

0

不知道这是否能够解决您的问题,但是您使用会话作用域支持bean并基于上面的代码段,可能确实会请求作用域bean,因为我没有真正看到其中需要保存会话的很多内容。我也会考虑使用可能的视图范围,如果它可用并重新构造bean,所以您可以从不需要对数据库进行多次调用中受益,因为jsf是多次调用后备bean的臭名昭着的,就像这样。

@Named("galleryBean") 
@RequestScoped // or @ViewScoped 
public class GalleryBean implements Serializable { 

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("imagePU"); 

    private List<TaggedImage> images = null; 

    public List<TaggedImage> getTaggedImages() { 
     if (this.images != null) { 
      return this.images; 
     } 
     EntityManager em = emf.createEntityManager(); 
     try { 
      EntityTransaction entr = em.getTransaction(); 
      boolean committed = false; 
      entr.begin(); 
      try { 
       Query query = em.createQuery("SELECT ti FROM TaggedImage ti GROUP BY ti.tag ORDER BY ti.taggedImagesId DESC"); 
       images = query.getResultList(); 
       entr.commit(); 
       committed = true; 
      } finally { 
       if (!committed) { 
        entr.rollback(); 
       } 
      } 
     } finally { 
      em.close(); 
     } 
     return images; 
    } 
} 

更重要的是,你会分离出来,从数据库中TaggedImage的实际取,并把它的地方,它被称为具有@PostConstruct或@URLAction豆施工阶段的一部分,如果使用漂亮的面孔和getTaggedImages( )真的只是成为另一个吸气剂/设置器

+0

首先,感谢您的示例代码,我需要它。而且我知道其实我不需要会话作用域bean,但我认为这些所有其他性能优化点并非主要原因。会话超时后,所有内容都必须从与会话相关的堆中释放。 – Deniz