我正在尝试将 512MB 文件读入 java 内存。这是我的代码:
String url_part = "/homes/t1.csv";
File f = new File(url_part);
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
ArrayList<String> mem = new ArrayList<String>();
System.out.println("Start loading.....");
System.gc();
double start = System.currentTimeMillis();
String line = br.readLine();
int count = 0;
while(line!=null){
line=br.readLine();
mem.add(line);
//System.out.println(count);
count++;
if(count%500000==0){
System.out.println(count);
}
}
文件包含 40000000 行,在读取 18500000 行之前性能完全正常,但在读取大约 20000000 行后就卡在某个地方了。 (这里就卡住了,但是等了很久,大约10秒后继续)
我跟踪了内存使用情况,发现即使总文件大小只有 512 MB,运行程序时内存也会增长约 2GB。此外,8 核 CPU 保持 100% 利用率工作。
我只是想将文件读入内存,以便稍后我可以更快地从内存中访问我想要的数据。我的做法正确吗?谢谢!
最佳答案
首先,Java 以 UTF-16 存储字符串,因此如果您的输入文件主要包含 latin-1 符号,那么您将需要两倍的内存来存储这些符号,因此 1Gb 用于存储字符。其次,每条线路都有一定的开销。我们可以粗略估计一下:
- 从
ArrayList
到String
的引用 - 4 个字节(假设压缩的 oops) - 从
String
到char[]
数组的引用 - 4 个字节 String
对象 header - 至少 8 个字节hash
字符串字段(用于存储 hashCode)- 4 个字节char[]
对象 header - 至少 8 个字节char[]
数组长度 - 4 字节
因此每行总共至少会浪费 32 个字节。通常它更多的是因为必须填充对象。因此,对于 20_000_000 行,您至少有 640_000_000 字节的开销。
关于java - java读取数据到内存的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31656737/