2016-03-22 5 views
1

以下のメソッドはforループを2つ持っています。 Firstloopは36000回繰り返し、inner forloopは24回反復するので、レコードの総数は864000になります。 コード実行は約3.5時間実行され、終了します(レコードの挿入に失敗しました)。 セッションの終了とトランザクションのコミットは外側forループの終了後にのみ作成されます。 [全GC(人間工学)[PSYoungGen:979968K私がメモリの割り当てにガベージコレクションがJavaで動作しないようです

17034.595を示すために、GCログの最後の数行を添付した

@SuppressWarnings("unchecked") 


public void createBRResults() { 

    List<BusinessRules> businessRuleList = null; 
    Organization organization = null; 
    Brresults brresults = null; 
    Criteria criteria = null; 
    Criteria newCriteria = null; 
    String brStatus = "Live"; 
    Date date = new Date(); 
    Session session = sessionFactory.openSession(); 
    Transaction transaction = null; 
    try { 
     if (callInfos == null) { 
      callInfos = getEntities(CallInfo.class); 
     } 
     for (CallInfo callInfo : callInfos) { 
      transaction = session.beginTransaction(); 
      criteria = session.createCriteria(BusinessRules.class); 
      criteria.createCriteria("businessGoals").add(
        Restrictions.eq("category", callInfo.getCategory())); 
      businessRuleList = criteria.list(); 
      organization = callInfo.getOrganization(); 
      for (BusinessRules businessRule : businessRuleList) { 
       brresults = new Brresults(); 
       brresults.setBusinessRule(businessRule); 
       brresults.setCallInfo(callInfo); 
       brresults.setCreatedDate(date); 
       brresults.setModifiedDate(date); 
       brresults.setOrganization(organization); 
       brresults.setBrrStatus(brStatus); 
       brresults.setBrrValue(Math.random() < 0.5 ? 0 : 1); 
       session.save(brresults); 
       brresults = null; 
      } 
      criteria = null; 
      organization = null; 
      businessRuleList = null; 
      session.flush(); 
      session.clear(); 
      transaction.commit(); 
      System.gc(); 
     } 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } finally { 
     session.close(); 
    } 
} 

RAMの消費量は、実行中にほぼ6.9ギガバイトであることが判明しました - > 979964K(1862144K)] [ParOldGen:5576158K-> 5576158K(5576192K)] 6556126K-> 6556123K(7438336K)、[メタスペース:23195K-> 23195K(1071104K)]、2.1041939秒] [時刻:user = 8.61 sys = 0.00実= 2.11秒]

17036.699:[フルGC(エルゴノミクス)PSYoungGen:979968K-> 979964K(1862144K)] [ParOldGen:5576158K-> 5576158K(5576192K)] 6556126K-> 6556123K(7438336K)、[メット[完全なGC(人間工学)] [PSYoungGen:979968K-> 979964K(1862144K)] [完全なGC(人間工学)[スペース:23195K-> 23195K(1071104K)]、1.5930338秒] [時刻:ユーザー= 9.39 sys = 0.00、現実= 1.59秒] 17038.292 [ [ユーザー:8.51 sys = 0.00、現実= 1.94秒]

:095301K:> 6556126K-> 6556122K(7438336K)、[メタ空間:23195K-> 23195K(1071104K)]、1.9376959秒]

17040.230:[フルGC(エルゴノミクス)PSYoungGen:979968K-> 830418K(1862144K)] [ParOldGen:5576158K-> 5576027K(5576192K)] 6556126K-> 6406445K(7438336K)、[メタスペース:23196K-> 23196K(1071104K) ]、2.9929302秒] [時間:ユーザー= 17.97 SYS = 0.00、リアル= 3.00秒]

ヒープ889367K [0x0000000715d80000、0x00000007bdc80000、0x00000007c0000000使用PSYoungGen総1862144K)空間885760Kに空間882176Kから、90%の使用

エデンスペース979968K [0x0000000715d80000,0x000000074c205e48,0x0000000751a80000) 、0%が使用[0x0000000787f00000,0x0000000787f00000,0x00000007bdc80000) 、0%が使用[0x0000000751a80000,0x0000000751a80000,0x0000000787b80000) ParOldGen 5576192K合計、[0x00000005c1800000,0x0000000715d56d38,0x0000000715d80000) メタスペースは、容量23502Kを23223Kを使用24064Kを犯し、コミット1071104K 2443Kを使用するクラス空間、容量2537Kを、予約5576027K [0x00000005c1800000、0x0000000715d80000、0x0000000715d80000) オブジェクト空間5576192K、99%が使用される使用2560K、予約済み1048576K

しかし、私はセッションを閉じて、24反復ごとに再び開くと、レコードの挿入が成功し、それに要する時間は55分です。 RAMの使用率は約3GBです。

なぜガベージコレクションが正しく行われていないのですか?コードのバグは何ですか?

答えて

4

Sessionは、同じセッション内で2回尋ねると正確に同じオブジェクトを返さなければならないため、タッチしたすべてのオブジェクトへの参照が蓄積されています。コンテキストを破棄できるように、定期的に閉じておく必要があります。

+0

繰り返しを繰り返すたびにセッションを終了するように指示していますか?もしそうなら、バッチ挿入をする正しい方法ですか? – Popeye

+0

@sriram私はそれを定期的に閉じると言っています。これは、反復ごとに行うことも、他の間隔で行うこともできます。セッションが強力なキャッシュとアカウントを保持していることを認識するだけで済みます。 – chrylis

関連する問題