我有一个树形结构,在oracle表中存储了非常大的数据集,在加载数据时,我得到了java.lang.OutOfMemoryError。以下是完整的场景:
树层次结构存储在Db表" Tree_Hierarchy"
中 A
/ \
B C
/ \
D E
Tree_Hierarchy表数据:
Id Node_Name Parent_Id 1 A 2 B 1 3 C 1 4 D 2 5 E 2
每个节点(A,B,C等)至少包含20,000条记录,最多可增加50,000条记录。这些记录存储在单独的表" Tree_Data"中。所以Tree_Data表包含来自每个节点的所有记录信息。树层次结构/级别也可以增长到30级。 Tree_Hierarchy和Tree_Data都是JPA实体
Tree_Data表结构:
Id Node_Name Column1, Column2, Column3,.........,Column70 1 A dataA11, dataA21, data13,........., data170 2 A dataA21, dataA22, data23,........., data270 ... 30001 B dataA11, dataA21, data33,........., data370 30002 B dataA21, dataA22, data43,........., data470 ... 60001 C dataA11, dataA21, data53,........., data570 ... 90001 D dataA11, dataA21, data63,........., data670 ... 120001 E dataA11, dataA21, data73,........., data770
问题陈述:
我必须将树层次结构中的所有节点与Column1,Column2中的相同数据组合成" Map< Key,List< Tree_Data>>"使用key作为ID_NodeName_Column1_Column2,然后对数据执行一些分析。
因此,对于具有3个级别的上述树结构,Map中将有30000个条目/组,其中包含5个元素(每个元素来自A,B,C,D,E)。
当前情况: 目前我已经实现了这一点:首先,我将树结构加载到列表中,然后将所有节点的所有数据加载到内存中(这意味着我将30000 * 5 = 150000 jpa实体加载到内存中),然后使用Java 8流对这些实体进行分组
问题: 上面提到的单个请求场景与4Gb的堆大小(仅与树级别5)一起工作正常,但是一旦第二个请求到来,就会遇到java.lang.OutOfMemoryError。我知道将这样一个大对象加载到内存中是疯狂的,甚至16Gb的堆大小也不适用于38级的树级。
作为替代解决方案,我试图从db本身加载分组数据。任何人都可以为我提供从db加载分组数据或建议任何其他方法的解决方案。
提前致谢。
答案 0 :(得分:0)
您绝对不需要将所有数据都加载到内存中。而是定义要加载的分页逻辑100条记录。添加
criteria.setFirstResult()
criteria.setMaxResults()
加载前100条记录,处理它们并加载下一条100.继续直到处理完所有记录。
更好的是,您可以同时加载和处理多个页面,并使用并行流进行分组。