问题
First, a little background. I am working on Management Software that pulls data from an SQL Server. I am using JPA to create Entity instances of the tables for manipulation within the management software (I've only been using JPA for a couple of days now). As a test, I threw together the below code to test how much memory would be taken up storing objects of their most abundant table (PeriodicalTable) which has 18,500 rows (or there abouts) and is only likely to grow;
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<PeriodicalTable> 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();
}
The above code throws java.lang.OutOfMemoryError: Java heap space even though I have raised -Xmx to 512m. I don't want to use any more memory because the computers this software will be running on only have roughly 2GB of RAM. Now, I could use .setMaxResults() against each query (as you can see commented out), but that's not ideal because I will need to display all of them in the final product.
So, the question. Are there any more memory efficient methods of running toString on every Entity in a table, whilst using JPA? What are the pros and cons of these different methods? I had thought about maybe only storing a list of the String values passed by .toString() but can't think of a way of doing that without first using .getResultList() and storing the results in a list first.
Edit: As a side, I am using Java Standard JPA and haven't looked into Hibernate or ObjectDB or anything like that. Unless their use is essential I intend to avoid learning about more technologies than is necessary.
回答1:
You could try paginating the results with query.setMaxResults() and query.setFirstResult(). That way you can load the results in chunks of for example 2500 rows.
回答2:
Generally speaking, ORM's are not proper to load and handle large amounts of data. No matter how efficient your implementation is, ORM will use so much memory and CPU as they are highly relying on reflection. As you may see in their documentations, they are designed for Load-Modify-Persist scenarios. If you need to load and show large amount of data, you definitely will need pagination.
回答3:
Please check the PeriodicalTable mappings and lazy load objects.
来源:https://stackoverflow.com/questions/18508271/jpa-memory-management-issues