现在有代码
String str = new String("abc");
String str1 = str;那我如果str1 = null;那么str的内存是不是不会得到回收?
怎么回收str的空间呢?
我有一个好几千万的循环,所以需要及时的回收内存。
实际问题就是读文件,文件几千万行,堆现在是256m,不希望继续扩了。
while ((oneLine = reader.readLine()) != null)
这一行会报内存不足 java.lang.OutOfMemoryError: Java heap space
查看了readLine的源代码,里面会new一个string,类似上述的问题,所以发这个帖子求助大家。
String str = new String("abc");
String str1 = str;那我如果str1 = null;那么str的内存是不是不会得到回收?
怎么回收str的空间呢?
我有一个好几千万的循环,所以需要及时的回收内存。
实际问题就是读文件,文件几千万行,堆现在是256m,不希望继续扩了。
while ((oneLine = reader.readLine()) != null)
这一行会报内存不足 java.lang.OutOfMemoryError: Java heap space
查看了readLine的源代码,里面会new一个string,类似上述的问题,所以发这个帖子求助大家。
应该是读出来的这些内容大小超出了堆的可用大小。如果每行数据比较大的话,几千万行的数据大小也不是小数目
我对oneLine = reader.readLine()处理了下,没有保存
但是有oneLine = null 提示回收呀
文件中每行并不长
就是两个int 中间用空格分隔
如果文件不大的话,可能程序其他地方也占用了大量内存,这里只是加剧了内存占用,是导火索
reader.readLine()确实是导火线 文件很大 5000w条 但是每条记录就是两个int
{
int idx = oneLine.indexOf('\t');
for(int i = 0; i < idx; i++)
{
strBuffer1.append(oneLine.charAt(i));
}
for(int i = idx + 1,len = oneLine.length(); i < len; i++)
{
strBuffer2.append(oneLine.charAt(i));
}
FollowerId = Integer.valueOf(strBuffer1.toString()).intValue();
FolloweeId = Integer.valueOf(strBuffer2.toString()).intValue();
strBuffer1.delete(0, strBuffer1.length());
strBuffer2.delete(0, strBuffer2.length());
oneLine = null;
//构建哈希表
ArrayList value = map.get(FollowerId);
if(value == null)
{
ArrayList arrayList = new ArrayList();
arrayList.add(FolloweeId);
map.put(FollowerId, arrayList);
}
}
补充下 文件格式是 两个int
11111111 3456
我是要分隔 然后把int放入hash表
ArrayList arrayList = new ArrayList();
arrayList.add(FolloweeId);
map.put(FollowerId, arrayList);
有什么办法吗
String cuts[] = oneLine.split("\t");
就得到两个字符串,然后:
FollowerId = Integer.valueOf(cuts[0]);
FolloweeId = Integer.valueOf(cuts[1]);
然后还突然发现你最后那个构建哈希表应该有逻辑错误。
文件总规模: 5000w个 int \t int
String cuts[] = oneLine.split("\t"); 使用这个也会内存溢出,因为split底层使用的substring会引用分割前大的string的char数组,导致空间不足
逻辑错误是指使用arraylist吗
主要是要处理一对多的
ArrayList value = map.get(FollowerId);
if(value == null) {
ArrayList arrayList = new ArrayList();
arrayList.add(FolloweeId);
map.put(FollowerId, arrayList);
}
哦不好意思忘了一个else
else
{
value.add(FolloweeId);
}另外 其实可以不需要parseInt(),浪费速度和对象数量
这句不理解?
这个规模我想很难完整装载进JVM了,尤其是你还想节省内存的话。List和Map自己的内存结构都是不小的开销,尤其Map有大量指针存储开销。你可以测试看看,把List和Map都去掉,哪怕把内存降低为128MB,也能正常跑完的。ArrayList value = map.get(FollowerId);
/*if(value == null) {
ArrayList arrayList = new ArrayList();
arrayList.add(FolloweeId);
map.put(FollowerId, arrayList);
}*/要么就要用64位JVM,继续放大内存;要么就得换种算法了。