在Java中保存用于批处理的数据集合的最佳实践

在Java中保存用于批处理的数据集合的最佳实践,java,multithreading,memory,collections,Java,Multithreading,Memory,Collections,我有一个生成记录的数据生成代码,每个记录由多个用户选择的字段组成。为了加快进程,我将任务拆分为批量创建记录,并行创建记录 例如:如果我想生成10k记录,我将其拆分为5个任务 喜欢说 Task 1 : create record from 1-2k Task 2 : create record from 2001-3k ... Task 5 : create record from 8001-10k 我希望每个线程在容器中存储记录。当容器被填充到一个极限(比如初始1k记录)时,一个

我有一个生成记录的数据生成代码,每个记录由多个用户选择的字段组成。为了加快进程,我将任务拆分为批量创建记录,并行创建记录

例如:如果我想生成10k记录,我将其拆分为5个任务

喜欢说

 Task 1 : create record from 1-2k

 Task 2 : create record from 2001-3k

 ...

 Task 5 : create record from 8001-10k
我希望每个线程在容器中存储记录。当容器被填充到一个极限(比如初始1k记录)时,一个等待导出数据的任务将开始按顺序删除记录

我的选择是使用散列映射,因为序列很重要,但它的内存效率并不高,因为即使映射为空超过50%,堆上映射的大小也会保持不变,直到映射为GC


那么考虑到我上面的场景,什么是最适合集装箱的呢

阅读这些帖子可能会有所帮助:


当您谈论大容量时,将记录存储在内存中不是一个好的做法。批量检索数据时,将数据推送到持久性数据库存储。 如果为数据保留索引id,则可以从此处处理存储顺序

如果您喜欢使用Hashmap: 可以在初始化对象时指定负载率。这将限制基础哈希表中未使用的空间量。当然,限制这个未使用的空间会导致性能下降,因为哈希表中会有更多的冲突。 你还需要调整你的GC,看看这个-


但是我仍然建议您按照之前的建议修改您的设计

您可能不需要关心垃圾收集器。只有在调用垃圾收集器时,才会释放所有内存—它永远不会更早释放。如果您的程序功能正确,并且没有保留对未使用数据的任何引用,那么垃圾收集器将清除所有未使用的对象

请看这里的问题:

可以使用数组存储对对象的引用。如果使用新引用覆盖引用,则垃圾收集器将收集数组中的旧对象。否则,您将不得不丢弃该数组,或者手动将任何未使用的引用设置为null,以允许GC重用这些引用

可以使用
ArrayList
,在这种情况下,可以调用
clear()
将其清空并释放引用。或者您可以扔掉
ArrayList
并重新分配它

此外,请参见此处:


如果你真的想避免分配和重新分配内存,你就必须担心重用保存单个记录的对象,这可能会非常困难,而且可能不会有效。

ArrayList是一个不错的选择。ArrayList具有移除方法,该方法应用于移除对象。ArrayList clear()方法也会有所帮助。但是,正如您所指出的,您必须等待GC

内存效率最高的方法是使用基本数据类型,如字符数组和整数数组。这是因为Java中的原始数据类型是唯一没有垃圾收集的数据类型


在Java中,除了primitive之外的所有东西都是对象。所有对象在实例化时都有内存分配,没有获得释放的选项,但有资格进行垃圾收集。

我更喜欢容器,而不是批处理
HashMap
不保留序列。为什么不使用数组?我正在HashMap中添加索引作为键,那么为什么不使用一个数组,它的索引作为隐式键?在数组中,如果我开始删除对象,内存不会被释放。只有当GCWe将其存储到持久性数据库时,才会发布该文件,以防检索频率较低,如每5秒1条记录