2013-09-22 68 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