我有一个Java EE应用程序如下:
- 服务器在亚马逊(大型实例,2 CPU @ 2.27GHz,8GB RAM)
- Apache直接提供的静态内容
- 在Glassfish 3.1.1上运行的JSF2(Mojarra 2.1.3)和JPA 2(Eclipselink 2.3.0)
- Facelets / XHTML从ViewScoped托管bean获取内容,这些bean连接到执行所有处理的@Local Stateless EJB,包括从使用JPA的其他@Local Stateless EJB获取数据
通常如此:
XHTML --> ViewScoped Managed Bean --> Service EJB --> Data EJB --> JPA
我知道我可以/应该删除2层EJB到一个甚至没有,因为我只运行了一个Glassfish实例,但是现在我认为这不是问题。
应用程序的性能还可以(2.2MB包括< 5s中的图像)。问题是,当我们有>在线的90个用户系统变得非常慢(每页大约30秒,即使大部分是高速缓存的) 那时CPU使用率为50%,RAM使用率为100%。
所以我跑了JProfiler,我不知道如何处理一种结果。
在主页中,我们有一个类别列表,并且每个类别都有一些产品(一个购物网站,告诉每个类别有多少产品)。获取类别列表的代码是:
ViewScoped Bean
public List<Category> getLiveCategoriesInfo() {
if (liveCategories == null) {
liveCategories = liveCategoryService.getLiveCategories(getLocale().getLang().getLanguageId());
}
return liveCategories;
}
从使用ManagedProperty 注入的SessionScoped Bean中检索 getLocale()
服务EJB:
public List<Category> getLiveCategories(final Integer langId) {
List<LiveCategory> lives = categoryBean.getLiveCategories(langId);
// ... some processing involving looping through the list above
return livesCategories;
}
数据EJB:
public List<LiveCategory> getLiveCategories(final Integer langId) {
List<LiveCategory> categories = new ArrayList<LiveCategory>();
Query cq = getEntityManager().createNamedQuery(Category.FIND_LIVE);
try {
categories = cq.getResultList();
} catch (NullPointerException npe) {
// ...
}
return categories;
}
JProfiler内存视图显示,在主页上的每个请求(即使是同一个用户)中,新的一批类别被添加到内存中(准确地说是43,这是显示的类别数)。类别不由JPA管理(JPA中的列表用于手动创建POJO) 如何从内存中释放这些实体。当视图消失时,我希望它们是GC。但ViewScoped bean本身不是GC'd,有一堆实例留在内存中。
我应该寻找什么来释放这些物品?
- 在ViewScoped bean中使用@ManagedProperty
来获取SessionScoped bean的实例,防止ViewScoped bean被GC化吗?
- 我应该寻找其他的错误吗?
我确实检查了有关JSF最佳实践和性能指南的其他主题,但它没有帮助。
答案 0 :(得分:0)
可能是您可以尝试在用户注销时释放FacesContext。
答案 1 :(得分:0)
我认为您的问题与您使用视图范围和会话范围的方式有关。简而言之,您正在使用在页面生命周期内不会更改的对象填充内存。相反,您应该使用请求范围bean仅在处理请求时缓存这些结果,并使用@ManagedProperty注释或其他任何内容(创建值表达式或调用Application.evaluateExpressionGet来从视图范围或会话范围bean中获取参数通过这种方式,当请求结束时,将释放对实体的引用,并且GC将收集它们。
如果您对性能部分真的感兴趣,请查看此博客:
Understanding JSF 2 and Wicket: Performance Comparison
测试代码已经过调整,以获得JSF和Wicket的最佳性能。调整JSF非常简单,因此您通常应该观察ORM工具以获得性能提示。