我有一个数据结构:
ArrayList<String>[] a = new ArrayList[100000];
每个列表包含大约1000个字符串,大约100个字符。
我正在做一次性的工作,而且它的成本要比我能承受的多一点。
我认为如果能找到降低内存成本的方法,我可以改变更少的代码,因为成本不是太高,而且它只是一次性的工作。所以,请告诉我你知道的所有可能方式。
添加一些信息:我使用arraylists数组的原因是我现在可以知道100000的大小。但在我处理所有数据之前,我并不知道每个arraylist的大小。
问题确实是数据太多,所以我想找到压缩它的方法。这不是分配问题。最终会有太多数据超出内存。
答案 0 :(得分:1)
它的成本比我承受的要多一点
那么,“有点”多少钱?
一些快速估计:
您拥有1000x100个字符的字符串集合。这应该是大约1000x100x2 = 200kb的字符串数据。
如果您有100000个,那么仅数据就需要近20Gb 。
与每个集合数据的200kb相比,数据结构的开销微乎其微,即使每个集合的内容为100字节(0.05%)。
所以,在这里获得的并不多。
因此,唯一可行的方法是:
某种数据压缩以减小20Gb有效载荷的大小
使用外部存储,例如通过只阅读当前需要的字符串然后丢弃它们
对我而言,目前尚不清楚您的内存问题是否真的来自您展示的数据结构(您是否对程序进行了分析?)或者是程序的总内存使用情况。正如我在另一个答案中评论的那样,例如,临时调整数组(列表)的大小至少需要复制操作的数组(列表)大小的2倍。然后注意你可以在Java中创建内存泄漏 - 或者只是保留你实际上不再需要的数据。
Java中的String
由char
个数组组成。每个字符都占用两个字节。
您可以将String
转换为byte[]
,其中任何ASCII字符只需要一个字节(非ASCII字符仍需要2个(或更多)字节):
str.getBytes(Charset.forName("UTF-8"))
然后你为Comparator
制作一个byte[]
,你很高兴。 (请注意byte
的范围为[-128,127],这使得在这种情况下进行非直观比较;您可能希望比较(((int)byteValue) & 0xff)
。
答案 1 :(得分:0)
为什么在编译时本身不知道大小时使用数组,大小是主要关注的原因链接列表优于数组
的ArrayList&LT; String&gt; [] a = new ArrayList [100000];
为什么一次分配内存 最初,ArrayList会在需要时resize
自己手动执行此操作。
我认为以下结构足以满足您的要求
List<List<String> yourListOfStringList = new ArrayList<>();