Oracle 的 Jena 改编中的内存泄漏?

Memory leak in Oracle's Jena adaptation?

(注意;这也在 OTN 讨论论坛上被问到 - 但我不太确定那里有多少 activity)

我使用 rdf_semantic_graph_support_for_apache_jena_2.11.1_with_12101_server_patch_build0529 进行了测试,并在 运行 附加测试-class 的 main() 方法时观察到 OOM 行为。

虽然我不知道为什么。 在 MAT 中,似乎有一大堆 Oracle 实例在周围徘徊,拥抱很多 Strings - 但我可以通过 SQL*Developer 验证连接是否已成功关闭。

剥离测试,我看到明显的泄漏发生在与 ModelOracleSemGraphOracleSem 的任何交互上。

public class OracleSemTxIntegrationWithSpringITCase {
    private OracleDataSource oracleDataSource;
    private OraclePool oraclePool;

    @Before
    public void before() throws SQLException {
        java.util.Properties prop = new java.util.Properties();
        prop.setProperty("MinLimit", "2");     // the cache size is 2 at least
        prop.setProperty("MaxLimit", "10");
        prop.setProperty("InitialLimit", "2"); // create 2 connections at     startup
        prop.setProperty("InactivityTimeout", "200");    //  seconds
        prop.setProperty("AbandonedConnectionTimeout", "100");  //  seconds
        prop.setProperty("MaxStatementsLimit", "10");
        prop.setProperty("PropertyCheckInterval", "60"); // seconds


        oracleDataSource = new OracleDataSource();
        oracleDataSource.setURL("jdbc:oracle:thin:@**********");
        oracleDataSource.setUser("rdfuser");
        oracleDataSource.setPassword("****");
        oracleDataSource.setConnectionProperties(prop);


        oraclePool = new OraclePool(oracleDataSource);
    }


    @Test
    public void testTransactionHandlingViaJdbcTransactions() throws Exception {
        final Oracle oracle1 = oraclePool.getOracle();
        final Oracle oracle2 = oraclePool.getOracle();
        final Oracle oracle3 = oraclePool.getOracle();


        final GraphOracleSem graph1 = new GraphOracleSem(oracle1,     OracleMetadataDaoITCase.INTEGRATION_TEST_MODEL);
        final Model model1 = new ModelOracleSem(graph1);
        final GraphOracleSem graph2 = new GraphOracleSem(oracle2,     OracleMetadataDaoITCase.INTEGRATION_TEST_MODEL);
        final Model model2 = new ModelOracleSem(graph2);
        GraphOracleSem graph3 = new GraphOracleSem(oracle3,     OracleMetadataDaoITCase.INTEGRATION_TEST_MODEL);
        Model model3 = new ModelOracleSem(graph3);


        removePersons(model3);
        model3.commit();
        model3.close();
        graph3 = new GraphOracleSem(oracle3,     OracleMetadataDaoITCase.INTEGRATION_TEST_MODEL);
        model3 = new ModelOracleSem(graph3);


        model1.add(model1.createResource("http://www.tv2.no/people/person-1"),     DC.description, "A dude");
        model2.add(model1.createResource("http://www.tv2.no/people/person-2"),     DC.description, "Another dude");


        int countPersons = countPersons(model3);
        assertEquals(0, countPersons);


        model1.commit();
        countPersons = countPersons(model3);
        assertEquals(1, countPersons);

        model2.commit();
        countPersons = countPersons(model3);
        assertEquals(2, countPersons);

        oracle1.commitTransaction();
        oracle2.commitTransaction();
        oracle3.commitTransaction();

        model1.close();
        model2.close();
        model3.close();

        oracle1.dispose();
        oracle2.dispose();
        oracle3.dispose();
        System.err.println("all disposed");
    }


    public static void main(String ...args) throws Exception {
        OracleSemTxIntegrationWithSpringITCase me = new     OracleSemTxIntegrationWithSpringITCase();
        me.before();
        Stopwatch sw = Stopwatch.createStarted();
        for(int n = 0; n < 1000; n++) {
            me.testTransactionHandlingViaJdbcTransactions();
        }
        System.err.println("DONE: " + sw.stop());
        me.after();
    }
    @After
    public void after() throws SQLException {
        oracleDataSource.close();
    }


    private int countPersons(final Model model) {
        return listPersons(model).size();
    }


    private void removePersons(final Model model) {
        final List<Resource> persons = listPersons(model);
        persons.stream().forEach(per -> model.removeAll(per, null, null));
    }


    private List<Resource> listPersons(final Model model) {
        final List<Resource> persons = Lists.newArrayList();
        ExtendedIterator<Resource> iter = model.listSubjects()
            .filterKeep(new Filter<Resource>() {
                @Override
                public boolean accept(Resource o) {
                    return     o.getURI().startsWith("http://www.tv2.no/people/person-");
                }
            })
            ;
        iter.forEachRemaining(item -> persons.add(item));
        iter.close();
        return persons;
    }
}

Oracle 已经为此提供了一个修复程序,我认为它会在某个时间公开可用。