交换过程中本机内存正在增加

时间:2016-05-02 06:54:06

标签: java memory websphere hashtable heap-memory

我有一个在websphere服务器中每小时都有效的功能。

很快,该函数从数据库读取数据并与旧数据交换数据。在对此函数进行新调用之前,它会将数据存储在内存中,以便在在线请求中提供快速响应。

我的问题在于,正常情况下,在交换过程开始时,我的堆正在增加重复数据,因此交换过程结束时我释放了所有临时变量,而我的堆正在减少。因此,交换过程之前的内存使用量和交换过程之后的内存使用量是相同的。

但是本机内存(java本机库内存)总是在增加,它在交换进程/函数结束时或者当我释放所有临时变量时都不会减少。我找不到导致它的原因。

这是我的功能

private void PopulateTL(String projectName) throws Exception {

    // Setting old models
    Hashtable<String, PreparedStatement> scoringFormulaMapCurrent = new Hashtable<String, PreparedStatement>();
    Hashtable<String, RSP_TL_Model> calibrationMapCurrent = new Hashtable<String, RSP_TL_Model>();
    Hashtable<String, PreparedStatement> scoringFormulaMapOld = scoringFormulaMapTL;
    Hashtable<String, RSP_TL_Model> calibrationMapOld = calibrationMapTL;

    // Getting new models
    String orgDbSource = masterConfigXML.getElement("Logging",
            "dbSource");
    String orgSql = masterConfigXML.getElement("orgSQL", "select"
            + projectName);
    Context ctx = new InitialContext();
    DataSource dataSource = (DataSource) ctx.lookup(orgDbSource);
    Connection connorg = dataSource.getConnection();
    PreparedStatement prepStmtorg = connorg
            .prepareStatement(orgSql);
    ResultSet rsorg = prepStmtorg.executeQuery();

    ArrayList<String> keys = new ArrayList<String>();

    while (rsorg.next()) {

        String ScoringSql = "";
        double Beta1 = 1.0;
        double Beta2 = 0.0;

        StringBuffer str = new StringBuffer();
        String strng;
        BufferedReader bufferRead = new BufferedReader(
                ((Clob) rsorg.getClob("SQL_FORMULA"))
                        .getCharacterStream());
        while ((strng = bufferRead.readLine()) != null)
            str.append(strng);
        ScoringSql = str.toString();
        if ((Double) rsorg.getDouble("SLOPE") == null)
            Beta1 = Integer.MAX_VALUE;
        else
            Beta1 = rsorg.getDouble("SLOPE");
        if ((Double) rsorg.getDouble("INTERCEPT") == null)
            Beta2 = Integer.MAX_VALUE;
        else
            Beta2 = rsorg.getDouble("INTERCEPT");
        if (rsorg.getInt("SAMPLE_COUNT") < 5) {
            Beta1 = 1;
            Beta2 = 0;
        }
        String key = String.format("%s-%s-%s-%s",
                rsorg.getObject("FLAG_VADE_NEW").toString(), rsorg
                        .getString("SPLIT"), rsorg.getObject("BALANCE")
                        .toString(), rsorg.getString("CHANNEL"));
        keys.add(key);
        if (projectName.equals("RSP_TL")) {

            PreparedStatement psFormula = inMemoryConn
                    .prepareStatement(regulateScoringFormula(ScoringSql,
                            projectName));

            scoringFormulaMapCurrent.put(key, psFormula);

            calibrationMapCurrent.put(key, new RSP_TL_Model(Beta1, Beta2));

        }
    }


    if (scoringFormulaMapCurrent.size() == 0) {
        throw new Exception(
                "RSPSERVER: "
                        + projectName
                        + "refresh failed. Returned zero records from formula table.");
    } else {
        // set global models from current models
        scoringFormulaMapTL = scoringFormulaMapCurrent;
        calibrationMapTL = calibrationMapCurrent;
        System.out.println("RSPSERVER: " + projectName
                + " Refresh completed..." + "Size of Hashtable: "
                + scoringFormulaMapTL.size());
        //close old models' preparedStatements
        for (int i = 0; i < keys.size(); i++) {
            if (scoringFormulaMapOld.get(keys.get(i)) != null) {
                ((PreparedStatement) scoringFormulaMapOld.get(keys.get(i)))
                        .close();
                calibrationMapOld.remove(keys.get(i));
            }
        }
        // clear old models' hash table
        scoringFormulaMapOld.clear();
        // deallocate current models
        scoringFormulaMapCurrent = null;
        calibrationMapCurrent = null;

        prepStmtOrganon.close();
        rsorg.close();
        connorg.close();
    }
}

本机内存每小时增加: native memory increasing every hour

  • jdbc version:10.2.0.1.0
  • oracle版本:oracle 11g 11.1
  • websphere版本:7.0.0.37
  • 服务器:unix redhat 5.11

1 个答案:

答案 0 :(得分:1)

您的主要问题是您正在创建PreparedStatement(s)e g prepStmtorg您没有关闭,这可能导致内存泄漏。我也建议

  • 您使用堆转储分析器(例如visualVM)来查看内存的保留位置。我更喜欢YourKit,因为我发现它比VisualVM更容易。
  • 不要使用Hashtable,因为它在Java 1.2中由HashMap替换
  • 不要使用StringBuffer,因为它已被Java 5.0中的StringBuilder取代(仍然是十年前)
  • 考虑使用RedHat 7.x,因为5.x已经很老了。 RedHat 5.x将于明年发布,即发布十年后即将结束。

我猜这是由其他人写的,可能是九年前。可能值得重新编写代码。

  

本机内存每小时增加

首先,我要确保您没有堆上的资源泄漏,这会导致堆中的资源泄漏。