我有一个带有测验的经典db结构,每个测验的问题集合,每个问题的答案集合,以及相关的实体类。
假设,测验有一百个问题,每个问题有一百个答案,我需要迭代每个问题,然后迭代每个答案,然后对每个答案做一些耗时的逻辑。所以整个循环的执行需要大量的时间。
如果我这样迭代:
for (Question q: quiz.getQuestions()) // triggers lazy loading of all questions of the quiz
{
for(Answer a: q.getAnswers()) // triggers lazy loading of all answers of the question
{
longReadOnlyProcessingOfAnswer(a);
}
}
在每次迭代答案之后,我不再需要它们了,但它们仍然在内存中,gc不会对它们进行处理。在这个漫长的执行过程结束时,包含所有问题和答案的测验将消耗大量内存(几十兆字节)
有没有办法通过保持这种懒散的加载方式来摆脱内存中不必要的对象?或者我应该直接从数据库获取答案?
1条答案
按热度按时间mctunoxg1#
把问题一个接一个地“蹦”出来
quiz.getQuestions()
. 一旦你处理完某个问题的答案,做一个EntityManager.flush()
同步更改,然后EntityManager.detach(question)
移除question
从持久性上下文。一定要有cascade = DETACH
在…之上Question.answers
. 这将使Question
s、 连同他们的Answer
他有资格做gc。(我假设
Quiz.questions
不是两个实体之间关联的所有者)您也可以尝试获取
Question
使用查询、处理它们、刷新,然后清除EntityManager
每批之后。这将允许您轻松地微调批处理大小以获得最佳性能。