有没有压缩java arraylist的方法?
我有一个数据结构:有没有压缩java arraylist的方法?,java,compression,Java,Compression,我有一个数据结构: ArrayList<String>[] a = new ArrayList[100000]; ArrayList[]a=新的ArrayList[100000]; 每个列表有大约1000个字符串,大约100个字符 我正在用它做一次性的工作,它花费的内存比我能承受的多一点 我想,如果我能找到降低内存成本的方法,我可以改变更少的代码,因为成本并不太高,而且这只是一次一次性的工作。所以,请告诉我你知道的所有可能的方法 添加一些信息:原因我;我使用数组列表是因为我现在知
ArrayList<String>[] a = new ArrayList[100000];
ArrayList[]a=新的ArrayList[100000];
每个列表有大约1000个字符串,大约100个字符
我正在用它做一次性的工作,它花费的内存比我能承受的多一点
我想,如果我能找到降低内存成本的方法,我可以改变更少的代码,因为成本并不太高,而且这只是一次一次性的工作。所以,请告诉我你知道的所有可能的方法
添加一些信息:原因我;我使用数组列表是因为我现在知道的大小是100000。但在我处理所有数据之前,我不知道每个arraylist的大小
问题是数据太多了,所以我想找到压缩数据的方法。这不是分配问题。最终将有太多的数据超出内存。为什么在编译时不知道大小的情况下使用数组,大小是主要问题,为什么链表比数组更可取 ArrayList
List<List<String> yourListOfStringList = new ArrayList<>();
列表
这花费了我无法承受的记忆
那么,“一点点”是多少
一些快速估算:
您拥有1000x100个字符的字符串集合。这应该是大约1000x100x2=200kb的字符串数据
如果您有100000个,那么仅数据就需要20Gb
与每个集合的200kb数据相比,数据结构的开销很小,即使每个集合的开销为100字节(0.05%)
因此,在这里没有多少收获
因此,唯一可行的方法是:
- 某种类型的数据压缩,以减少20Gb有效负载的大小
- 使用外部存储器,例如只读取当前需要的字符串,然后丢弃这些字符串
对我来说,不清楚您的内存问题是否真的来自于您显示的数据结构(您是否分析了该程序?)或该程序的总内存使用量。正如我对另一个答案所评论的,例如,临时调整数组(列表)的大小至少需要复制操作数组(列表)大小的2倍。然后请注意,您可以在Java中创建内存泄漏,或者只是保留实际上不再需要的数据
编辑:
Java中的String
由char
s数组组成。每个字符占用两个字节
您可以将字符串
转换为字节[]
,其中任何ASCII字符只需要一个字节(非ASCII字符仍需要2个(或更多)字节):
str.getBytes(Charset.forName(“UTF-8”)
然后为字节[]
制作一个比较器
,就可以开始了。(请注意,byte
的范围为[-128127],这使得在本例中比较不直观;您可能需要比较((int)byteValue)&0xff)首先,您是否同时需要所有列表?如果使用list a=new ArrayList(),则无需定义任何长度代码>。使用未完全填充的已定义列表大小(null
value)可能会占用您所需的内存。@AxelH。我认为是这样。我需要做的是在最后按顺序打印出来。数据以随机顺序出现。你需要通过整个算法获得所有可用的数据吗?甚至在最后?你有办法把数据分解成独立的部分吗?因为到目前为止,你提出的问题似乎不可能从总体上解决(即我有太多的数据,但我在计算的所有步骤中都需要这些数据),可能是重复的,但问题并不在开始。最后,存储的数据将过多。请注意,在将大小调整到至少2x list的操作过程中,峰值内存使用可能会增加。用于复制基础阵列的size()。OP正在创建一个列表数组,而不是一个巨大的arraylist。我们不知道他可能想要100000个列表。@JimmyB先生,我认为向量默认将其数组大小增加一倍,而ArrayList将其数组大小增加50%。@NeerajJain OP刚刚编辑了这个以添加此信息;)“添加一些信息:我之所以使用ArrayList数组,是因为我现在所知道的大小是100000”20Gb的数据压缩要达到至少8Gb(可能更小)会很复杂。因为它需要加载大量数据才能获得良好的压缩率。(取决于我知道的算法;)一年。数据约为20克。我可以获得26或27GB的内存。所以一些小小的压缩可能会有帮助。@AxelH。是的,可能性很大。错误和重新启动对我来说也是可以接受的,因为我只需要不到10分钟的时间来运行程序。@MallowFox我更担心的是,对于运行中的应用程序的其余部分,您将使用10分钟的可用内存(这是很多),在发生OutOfMemoryError
之后,这些可能不太容易重新启动。。。(但我不再滥发JimmyB答案)。@AxelH根据字符串的性质(自然语言?)你可以通过一个相对较小的几kb或mb的查找窗口获得适当的压缩。即使只是从char[]
(UTF-16)转换为byte[]
(ASCII)也可能节省50%。