1

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

堆转储:

一开始,我点击了应用程序中的所有网页,使用的堆大小为 100 MB:

之前的堆转储

1-2 天后,使用的堆大小增加到 300 MB(在此期间使用的网页相同):

之后的堆转储

我截取了堆中最常用的类的屏幕截图。

char[]类实例中,有太多这样的 SQL 查询字符串: 堆转储字符

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

@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;  
    }  
}  

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

谢谢你的帮助。

4

2 回答 2

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;  
    }  
}  

更好的是,如果使用漂亮的面孔和 getTaggedImages() 真的只是成为另一个 getter/二传手

于 2013-09-22T14:28:15.573 回答
0

我曾经在 JSF 页面上遇到过类似的问题,经过大量研究后发现问题是 JSF 在会话中保留的视图数量。不确定这是否是您的问题,但请查看配置视图数量。希望这可以帮助。

于 2013-09-22T14:01:45.147 回答