Java ArrayList<;双倍>;将[]翻一番,有3亿个条目
我正在使用java程序从数据库中获取一些数据。然后我计算一些数字并开始将它们存储在一个数组中。我用的机器有4吉格的内存。现在,我不知道预先会有多少个数字,所以我使用了一个Java ArrayList<;双倍>;将[]翻一番,有3亿个条目,java,memory,median,Java,Memory,Median,我正在使用java程序从数据库中获取一些数据。然后我计算一些数字并开始将它们存储在一个数组中。我用的机器有4吉格的内存。现在,我不知道预先会有多少个数字,所以我使用了一个ArrayList。但我知道大约会有3亿个数字。 因此,由于一个double是8字节,所以粗略估计这个数组将消耗2.4 Gig的内存(可能更多,因为ArrayList的开销)。在此之后,我想计算这个数组的中值,并使用org.apache.commons.math3.stat.description.rank.median库,该库
ArrayList。
但我知道大约会有3亿个数字。
因此,由于一个double是8字节,所以粗略估计这个数组将消耗2.4 Gig的内存(可能更多,因为ArrayList的开销)。在此之后,我想计算这个数组的中值,并使用org.apache.commons.math3.stat.description.rank.median
库,该库将double[]
数组作为输入。因此,我需要将ArrayList
转换为double[]
我确实看到了很多问题,它们都提到在整个阵列中循环是没有办法的。现在这很好,但由于它们也在内存中维护这两个对象,因此我的内存需求将达到4.8Gig。现在我们遇到了一个问题,因为总RAM为我们提供了4 Gig
首先,我是否怀疑该程序在某个时候会给我一个正确的内存错误(它当前正在运行)?如果是这样,我如何计算中位数而不必分配双倍的内存?我希望避免对数组进行排序,因为计算中位数是O(n)。您的问题甚至比您意识到的更糟,因为
ArrayList
的效率远远低于每个条目8个字节。每个条目实际上都是一个对象,ArrayList
保存一个引用数组。一个Double
对象大约有12个字节(4个字节用于某种类型的标识符,8个字节用于Double
本身),对它的引用再加上4个字节,使每个条目的总字节数达到16个,甚至不包括内存管理等开销
如果约束范围再宽一点,您可以实现自己的DoubleArray
,它由double[]
支持,但知道如何调整自身大小。但是,调整大小意味着您必须同时在内存中保留新数组和旧数组的副本,这也超出了内存限制
尽管如此,仍有一些选择:
- 循环输入两次;一次清点条目,一次将条目读入合适大小的
。当然,这取决于您的输入的性质,这是否可能double[]
- 假设最大输入大小(可能是用户可配置的),并预先分配一个固定大小的
。只使用已填充的部分double[]
- 使用
而不是float
将内存需求减半,但会牺牲一些精度double
- 重新考虑您的算法,避免将所有内容同时保存在内存中
Collections.sort(myArray);
final double median = myArray.get(myArray.size() / 2);
由于数据是从数据库中获取的,所以您可以告诉数据库给您中位数,而不是用Java,这将节省传输数据的所有时间(和内存)。有许多开源库为原语创建动态数组。其中一项:
我同意,使用Trove4j
t浮动数组列表
class(请参阅)存储双精度或t浮动数组列表
。结合前面的答案,我们得到:
// guess initialcapacity to remove requirement for resizing
TDoubleArrayList data = new TDoubleArrayList(initialcapacity);
// fill data
data.sort();
double median = data.get(data.size()/2);
写一段代码来说明你在做什么。如果数据在数据库中,为什么不使用数据库来执行计算?你说的是从查询中检索3亿行?你在用什么数据库?谢谢你的回答。。因此,double[]数组需要不超过8*大小的数组内存吗?或者这也会带来一些开销吗?double[]没有任何每元素开销,但是Collections.sort()可能会决定使用mergesort,这将需要加倍内存并引发错误(对吗?)或者在给定数组大小的情况下,它会知道使用快速排序吗?我不能直接使用sql,因为我对需要多个循环的数据进行处理。Collections.sort()也不能让您走得更远,因为它会带来双重装箱开销。如果您决定选择O(n log n),请过度分配,然后使用Arrays.sort()的3个参数变量: