0

次のようなJavaEEアプリケーションがあります
。-サーバーはAmazon上にあります(ラージインスタンス、2 CPU @ 2.27GHz、8GB RAM)-Apacheによって直接提供される静的コンテンツ
-JSF2(Mojarra 2.1.3)およびJPA 2(Eclipselink 2.3.0 )Glassfish3.1.1で実行-Facelets / XHTMLは、ViewScopedマネージドBeanからコンテンツを取得します 。これは、
JPAを使用する他の@Local Stateless EJBからのデータの取得を含む、すべての処理を行う@LocalStatelessEJBに接続します。

XHTML --> ViewScoped Managed Bean --> Service EJB --> Data EJB --> JPA

Glassfishのインスタンスを1つだけ実行している場合、EJBの2つのレイヤーを1つに削除するか、削除する必要があることはわかっていますが、今のところ、これが問題になるとは思いません。

アプリケーションのパフォーマンスは問題ありません(5秒未満の画像を含めて2.2MB)。問題は、オンラインのユーザーが90人を超えると、システムが非常に遅くなることです(ほとんどがキャッシュされている場合でも、ページあたり30秒以上)。
当時、CPUは50%使用され、RAMは100%使用されていました。

そのため、JProfilerを実行しましたが、1つのタイプの結果を処理する方法がわかりません。
ホームページにはカテゴリのリストがあり、各カテゴリにはいくつかの製品が関連付けられています(各カテゴリの製品の数を示すショッピングWebサイト)。カテゴリのリストを取得するためのコードは次のとおりです。

ViewScoped Bean

public List<Category> getLiveCategoriesInfo() {
    if (liveCategories == null) {
        liveCategories = liveCategoryService.getLiveCategories(getLocale().getLang().getLanguageId());
    }
    return liveCategories;
}

getLocale()ManagedPropertyを使用して注入されたSessionScopedBeanから取得されます

サービス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されておらず、メモリ内にとどまるインスタンスが多数あります。

これらのオブジェクトを解放するには、何を探す必要がありますか?
-ViewScoped Beanでを使用して@ManagedPropertySessionScopedBeanのインスタンスを取得しているため、ViewScoped BeanがGCされるのを防いでいますか?
-他に探すべき間違いはありますか?

JSFのベストプラクティスとパフォーマンスガイドラインについて他のスレッドを確認しましたが、役に立ちません。

4

2 に答える 2

0

ユーザーがログアウトしたときにFacesContextを解放しようとすることができるかもしれません。

于 2012-05-22T09:13:45.630 に答える
0

あなたの問題は、ビュースコープとセッションスコープの使用方法に関連していると思います。つまり、ページの存続期間中に変更されないオブジェクトでメモリを埋めているということです。代わりに、リクエストスコープBeanを使用して、リクエストの処理中にのみこれらの結果をキャッシュし、@ ManagedPropertyアノテーションなどを使用する必要があります(値式を作成するか、Application.evaluateExpressionGetを呼び出して、ビュースコープまたはセッションスコープBeanからパラメーターを取得します。そうすれば、エンティティへの参照はリクエストの終了時に解放され、GCによって収集されます。

パフォーマンスの部分に本当に興味がある場合は、次のブログを確認してください。

JSF 2とWicketを理解する:パフォーマンスの比較

テストコードは、JSFとWicketで最高のパフォーマンスが得られるようにすでに調整されています。JSFの調整は非常に簡単なので、通常はORMツールでパフォーマンスのヒントを確認する必要があります。

于 2012-05-22T09:20:34.713 に答える