JPA内存管理问题

首先,一点背景。 我正在研究从SQL Server中提取数据的管理软件。 我正在使用JPA创建表的Entity实例以便在管理软件中进行操作(我现在只使用JPA几天)。 作为测试,我将下面的代码汇总在一起,以测试存储多少内存将占用最丰富的表(PeriodicalTable)的对象,这些表有18,500行(或大约有)并且只能增长;

 public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersistenceDemoPU"); EntityManager em = emf.createEntityManager(); Query query = em.createQuery("SELECT p FROM PeriodicalTable p"); //query.setMaxResults(7000); List results = query.getResultList(); PeriodicalTable storedPlayer; for (int i = 0; i < results.size(); i++){ storedPlayer = results.get(i); System.out.println(storedPlayer.toString()); if (i == (results.size()-1)){System.out.println("Total results: "+(i+1)); } } em.close(); emf.close(); } 

上面的代码抛出java.lang.OutOfMemoryError: Java heap space即使我已经将-Xmx提升到512m。 我不想再使用内存,因为这个软件运行的计算机只有大约2GB的RAM。 现在,我可以对每个查询使用.setMaxResults() (正如你所看到的那样),但这并不理想,因为我需要在最终产品中显示所有这些。

所以,问题。 是否有更多内存有效的方法在表中的每个实体上运行toString,同时使用JPA? 这些不同方法的优点和缺点是什么? 我曾想过可能只存储.toString()传递的String值列表,但是如果没有先使用.getResultList()并将结果存储在列表中,就无法想到这样做的方法。

编辑:作为一方,我使用的是Java Standard JPA,并没有考虑过Hibernate或ObjectDB等等。 除非它们的使用是必不可少的,否则我打算避免学习更多的技术而不是必要的。

您可以尝试使用query.setMaxResults()query.setFirstResult()对结果进行分页。 这样,您可以将结果加载到例如2500行的块中。

一般来说,ORM不适合加载和处理大量数据。 无论您的实现效率如何,ORM都会使用如此多的内存和CPU,因为它们高度依赖于reflection。 正如您在其文档中看到的那样,它们是为Load-Modify-Persist场景设计的。 如果您需要加载并显示大量数据,您肯定需要分页。

请检查PeriodicalTable映射和延迟加载对象。