1

以下のメソッドには 2 つの for ループがあります。Firstloop は 36000 回反復し、内側の forloop は 24 回反復するため、レコード挿入の合計数は 864000 になります。コードの実行は 3.5 時間近く実行され、終了します。外側の for ループの終了後。実行時のRAM消費量は6.9GB近くあることが判明

@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();
    }
}

メモリ割り当てを示すために、GC ログの最後の数行を添付しました

17034.595:[完全なGC(人間工学)[PSYounggen:979968K-> 979964K(1862144K)] [PAROLDGEN:5576158K-> 5576158K(5576192K)] 65556126K> 6556114343434343434343434343434344343434 2.1041939 秒] [時間: user=8.61 sys=0.00, real=2.11 秒]

17036.699:[完全なGC(人間工学)[PSyounggen:979968K-> 979964K(1862144K)] [PAROLDGEN:5576158K-> 5576158K(5576192K)] 65556126K> 655611434343434343434343434343434343434 [Times: user=9.39 sys=0.00, real=1.59 secs] 17038.292: [フル GC (エルゴノミクス) [PSYoungGen: 979968K->979964K(1862144K)] [ParOldGen: 5576158K->557K6158K(55)7615] 1615 >6556122K(7438336K), [メタスペース: 23195K->23195K(1071104K)], 1.9376959 秒] [時間: user=8.51 sys=0.00, real=1.94 秒]

17040.230:[Full GC(Ergonomics)[Psyounggen:979968K-> 830418K(1862144K)] [PAROLDGEN:5576158K-> 5576027K(5576192K)] 6556126K-> 640645K(7445K(7445K)、236K(7445K) 2.9929302 秒] [時間: user=17.97 sys=0.00, real=3.00 秒]

ヒープ PSYoungGen 合計 1862144K、使用 889367K [0x0000000715d80000、0x00000007bdc80000、0x00000007c0000000)

eden space 979968K, 90% used [0x0000000715d80000,0x000000074c205e48,0x0000000751a80000) from space 882176K, 0% used [0x0000000787f00000,0x0000000787f00000,0x00000007bdc80000) to space 885760K, 0% used [0x0000000751a80000,0x0000000751a80000,0x0000000787b80000) ParOldGen total 5576192K, used 5576027K [0x00000005c1800000 、0x0000000715D80000、0x0000000715D80000)オブジェクトスペース5576192K、99%使用

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

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

4

1 に答える 1

4

Sessionは、同じセッション内で 2 回要求した場合、まったく同じオブジェクトを返す必要があるため、タッチしたすべてのオブジェクトへの参照を蓄積しています。コンテキストを破棄できるように、定期的に閉じる必要があります。

于 2016-03-22T06:05:56.687 に答える