我是一名c ++程序员,在找到JPA之后我正在玩java,这对于我目前的一些应用来说是神派.我从大学开始就没有触及java,我遇到了堆空间不足的问题.我正在使用下面的代码作为jdbc/jpa/lucene不太严重的测试的主要部分,但我继续得到随机的OutOfMemory异常.
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("select p from Product p" +
" where p.productid = :productid");
Connection con = DriverManager.getConnection("connection string");
Statement st = con.createStatement();
IndexWriter writer = new IndexWriter("c:\\temp\\lucene", new StandardAnalyzer(), IndexWriter.MaxFieldLength.LIMITED);
ResultSet rs = st.executeQuery("select productid from product order by productid");
while (rs.next()) {
int productid = rs.getInt("PRODUCTID");
q.setParameter("productid", productid);
Product p = (Product)q.getSingleResult();
writer.addDocument(createDocument(p));
}
writer.commit();
writer.optimize();
writer.close();
st.close();
con.close();
Run Code Online (Sandbox Code Playgroud)
我不会发布所有的createDocument,但它所做的只是实例化一个新的org.apache.lucene.document.Document,并通过add(new Field ...)等添加字段.总共有大约50个字段,大多数都是短的字符串(<32个字符)的长度.
在我的新事物中,有什么东西是完全愚蠢的我正在做(或不做)会导致事情不被GC?
是否有关于java内存管理和滴答GC的最佳实践?
我没有看到任何明显不合适的地方。如果您正在使用非常大的数据库,您可以尝试通过使用-Xmx n
JVM 调用中的选项来增加堆大小。这通常不是最好的解决方案 - 仅当您知道工作集大小实际上大于默认堆大小时才使用此解决方案。
您是否使用任何复杂的数据结构?如果对象之间存在循环引用,则可能会阻止垃圾收集器清理无法访问的对象。如果您有任何手写数据结构,请确保显式清空对已删除对象的引用,而不是执行诸如递减大小变量之类的操作。