0

ヒープ割り当てが大きいためにメモリ不足の問題が発生しています。HP Diagnosticsツールから検証しましたが、コード内でarraylistの要素を追加しています。オブジェクトを早期にリリースできるように、このコードをどのように記述すればよいかわかりません。以下のコードされていますJavaでOutOfMemoryの問題が発生しました

private List<UpperDTO> populateRecords(List<BaseEntity> baseEntityList,List<DataEntity> dataEntityList) { 

    List<UpperDTO> masterDTOList = new ArrayList<UpperDTO>(); 
    if(baseEntityList !=null && baseEntityList.size()>0){ 
     BigDecimal conId = null; 
     for(BaseEntity baseEntity :baseEntityList){ 
      conId = baseEntity.getConsignmentId(); 
      ArrayList<StatusData> statusDataList = new ArrayList<StatusData>(); 
      if(dataEntityList !=null && dataEntityList.size()>0){ 
       for(DataEntity data : dataEntityList){ 
        if(conId.equals(data.getConsignmentId())){ 
         //making null to supress from the response 
         data.setConsignmentId(null); 
         statusDataList.add(TrackServiceHelper.convertStatusDataToDTO(data)); 
        } 
       } 
      } 
      masterDTOList.add(TrackServiceHelper.populateDTO(baseEntity, statusDataList)); 
     } 
    } 
    return masterDTOList; 
} 

public static UpperDTO populateDTO(TrackBaseEntity baseEntity, 
     List<StatusData> statusList) { 

    UpperDTO upperDTO = new UpperDTO(); 
    //Setter methods called 
    upperDTO.setStatusData(statusList); 
    return upperDTO; 

} 

問題は、コードの行を次のように指摘されています

masterDTOList.add(TrackServiceHelper.populateDTO(baseEntity, statusDataList)); 

これは、JMSキューからメッセージを受信して​​、MDBは、これらのメッセージに耳を傾け、残りのAPIです。私はローカルまたはDev環境でこれをシミュレートすることができません。なぜなら、要求の数が多いときにパフォーマンステスト中に問題が発生するからです。これをどうすれば解決できますか?

これはHP Diagnosticsから収集漏れのスタックトレースです:

Chart Collection Class Contained Type Probe Collection Growth Rate Collection Size Leak Stack Trace Maximum Size 
0, 0, 255 java.util.ArrayList com.rex.ih2.dtos.UpperDTO gtatsh645 3,848 122,312 java.util.ArrayList.add(ArrayList.java:413) 
com.rex.ih2.utils.AppDAO.populateConsignment(AppDAO.java:168) 
com.rex.ih2.utils.AppDAO.searchConsignment(AppDAO.java:93) 
com.rex.ih2.service.AppService.fetchConDetail(AppService.java:131) 
com.rex.ih2.service.AppService.getConDetail(AppService.java:69) 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76) 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
java.lang.reflect.Method.invoke(Method.java:607) 
org.apache.webbeans.intercept.InterceptorHandler.invoke(InterceptorHandler.java:297) 
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:98) 
com.rex.ih2.service.TrackService_$$_javassist_0.getConsignmentDetail(TrackService_$$_javassist_0.java) 
com.rex.ih2.beans.TrackBean.action(TrackBean.java:35) 
com.tnt.integration.bean.AbstractServiceBean.invokeService(AbstractServiceBean.java:259) 
com.tnt.integration.bean.AbstractServiceBean.onMessage(AbstractServiceBean.java:157) 
com.rex.ih2.beans.TrackBean.onMessage(TrackBean.java) 
+0

これはあなたが提供した2つの方法よりもはるかに大きい質問です。これは、コードの質問ではなく、IMHOという設計上の疑問です。私がここで尋ねる質問は、この情報はどこから来ているのか、そしてどこへ行くのでしょうか? JMSとMDBについて言及します。一度に小さな塊で情報を扱うことは可能ですか? – dcsohl

+0

これは、データベース内で検索を行う必要のあるパラメータがほとんどないメッセージブローカからのリクエストメッセージを受け取るget APIです。この検索は、最初のメソッドで記述された2つのエンティティに移入します。これらのエンティティからは、別のDTOのリストもメンバー変数として持つDTOに値を設定する必要があります。このDTOは、応答オブジェクトに設定されます。 – Neel

+0

ページネーションなどを適用できますか?とにかく 'baseEntityList'と' dataEntityList'の大きさはどれくらいですか?多分もっと大きなヒープサイズが必要なだけかもしれません。 – dcsohl

答えて

0

私はdcsohiに同意します。これは実際には設計上の問題です。以下のアプローチを参照してください。 -

1)リストに追加されるオブジェクトのサイズ。最適化できるかどうか。 2)リスト内のすべてを一度に追加するのではなく、チャンクでデータを処理します。 3)JVM引数を最適化してヘッドサイズを増やし、より多くのオブジェクトを処理できるようにします。

dev環境でテストオブジェクトの数を増やし、ヒープサイズを減らしたり、プロダクションダンプを実行して同じボリュームで実行したりすることで、これをシミュレートできます。

+0

1)オブジェクトのサイズを小さくするにはどうしたらよいか分かりません。 2)要求ごとにフェッチされるデータの量は非常に少なく、要求が高い場合に問題が発生します。 3)このオプションは、コード自体をチューニングする他のオプションがない場合にのみ使用できます。 – Neel

+0

リストのサイズを確認してください。あなたがコメントで言及したものを見ると、それはあまり見えません。ヒープダンプも取ってみてください。 –

0

[OK]をクリックすると、DataEntityオブジェクトとBaseEntityオブジェクトの「委託ID」が一致しているかのように気になるようです。あなたは本当にデータベースクエリでこのようなことをする必要があります。エンティティオブジェクトを使用すると、JPA/Hibernateを介したDBインタラクションのように見えます。この場合、委託IDで2つのテーブルを結合し、出力に必要な情報を提供するDBビューを作成することができます。次に、このビューに一致するカスタム読み取り専用エンティティを作成します。次に、このビューのクエリにページネーションを適用し(必要な場合)、より小さなバッチで情報を取得することができます。

+0

クエリが非常に複雑であるため、私はデータベースに直接クエリを行っていません。私は記述に記載されたエンティティのリストをそれぞれ含む2つのrefcursorsを返すストアドプロシージャを呼び出しています。そのため、リストをループして、2番目のリストに同じ委託IDがあるかどうかを確認する必要があります。 – Neel

関連する問題