I have an Java EE application as follows:
- Server is on Amazon (large instance, 2 CPU @ 2.27GHz, 8GB RAM)
- Static content served directly by Apache
- JSF2 (Mojarra 2.1.3) and JPA 2 (Eclipselink 2.3.0) running on Glassfish 3.1.1
- Facelets/XHTML get content from ViewScoped managed beans, that connect to @Local Stateless EJB that do all the processing, including getting data from other @Local Stateless EJB that use JPA
So typically:
XHTML --> ViewScoped Managed Bean --> Service EJB --> Data EJB --> JPA
我知道我可以/应该把EJB的两层移到一个或甚至一个,因为我只运行过一只玻璃鱼,但现在我不认为这是问题所在。
The performance of the application is ok (2.2MB including images in < 5s). The problem is that when we have > 90 users online the system becomes really slow ( > 30 s per page, even if most of it is cached).
At that time the CPU was 50% used and RAM was 100% used.
So I ran JProfiler and I am not sure how to deal with one type of result.
In the homepage, we have a list of categories, and a number of product is associated to each category (a shopping website that tells how many product in each category). The code to get the list of Category is:
受观测的 Bean
public List<Category> getLiveCategoriesInfo() {
if (liveCategories == null) {
liveCategories = liveCategoryService.getLiveCategories(getLocale().getLang().getLanguageId());
}
return liveCategories;
}
getlocale ()
使用管理Property 从会话Scoped Bean 中提取到已注射的本地语言
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 Memory View shows that at every request on the homepage (even for the same user) a new batch of Category is added to the memory (43 to be precise, which is the number of categories displayed). The Category is not managed by JPA (the list from JPA is used to create POJO manually ).
How can I release these entities from the memory. I would expect them to be GC when the view is gone. But the ViewScoped bean is itself is not GC d, there is a bunch of instances that stay in memory.
What should I look for to release these objects?
- Is using a @ManagedProperty
in a ViewScoped bean to get an instance of SessionScoped bean preventing the ViewScoped one to be GC d?
- Is there some other mistake I should look for?
我查了JSF最佳做法和业绩准则的其他线索,但无济于事。