我用Java编写了一个小程序,用于将大文件分割成更小的文件。
代码如下:
import java.io.*;
public class Main {
final static int DIM = 6;
final static int GB = 1024 * 1024 * 1024;
public static void write(char[][] buffer, long currentFile) throws IOException {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("out" + currentFile + ".json"))) {
long wrote = 0;
for (int i = 0; i < DIM; i++) {
int firstNull = GB;
for(int j = GB - 1; j > 0; j--){
if(buffer[i][j] == '\0'){
firstNull = j;
}
}
bw.write(buffer[i], 0, firstNull);
wrote += firstNull;
}
bw.close();
System.out.println("Wrote " + wrote + " bytes to <out" + currentFile + ".json>");
}
}
public static void main(String[] args) {
System.out.println("Starting");
File file = new File("./twd.json");
long start = System.currentTimeMillis();
try {
int bufPos = 0;
int mapIdx = 0;
char[][] buffer = new char[DIM][GB];
long currentFile = 0;
BufferedReader br = new BufferedReader(new FileReader(file));
System.out.println("Config correct => Started");
String line;
while ((line = br.readLine()) != null){
if(bufPos + line.length() >= GB){
if(mapIdx == DIM - 1){
write(buffer, currentFile);
buffer = null; // Otherwise it will trigger OutOfMemoryError
buffer = new char[DIM][GB];
bufPos = 0;
double progress = GB * (currentFile + 1.0) / (file.length() / (double) DIM) * 100;
System.out.println("Status: " + progress + "%");
currentFile++;
mapIdx = 0;
}else{
mapIdx++;
bufPos = 0;
System.out.println("Map idx to " + mapIdx);
}
}
int i;
for(i = 0; i < line.length(); i++){
buffer[mapIdx][bufPos] = line.charAt(i);
bufPos++;
}
buffer[mapIdx][bufPos] = '\n';
bufPos++;
}
write(buffer, currentFile);
long end = System.currentTimeMillis();
br.close();
System.out.println("Diff: " + (end - start) / 1000 + "s");
}catch (IOException e){
System.out.println("IO Exception");
}
}
}
我遇到的问题如下,程序的内存使用量应该是DIM * GB * 2(一个字符是2个字节)GB。当 DIM = 5 时一切正常。如果我尝试增加它,它会抛出该错误。
我尝试传递一个额外的 -Xmx 参数来增加最大堆大小。但没有任何运气。 (我的系统有 48GB RAM,但甚至尝试指定 -Xmx(n)g,其中 n 是一个非常高的数字 (< 40) does not work.)
我注意到,在没有任何附加参数且 DIM = 5 的情况下,任务管理器向我显示该程序已达到 12GB RAM 的使用量。
我错过了什么吗?
我可以使用 6 以上的 DIM 运行你的程序。根据你的评论,你使用
java Main -Xmx32g
您需要将 VM 参数放在类名之前:
java -Xmx32g Main