由于某种原因,我的方法甚至在完成后也会耗尽内存



我正在编程一个神经网络,在该网络中,我将权重数据保存在一个长的txt文件中,因此为了检索数据,我使用"|"来分隔数字,然后在返回之前将其添加到数组中。

使用这种方法,我的内存使用量会达到1500MB,直到整个程序结束才会消失,但如果没有它,我的ram使用量会到达700

我试着关闭所有的东西,也许以为我的一个对象是一个线程,但这也不起作用。我的代码中有什么东西可能导致这种内存使用吗

这是代码:

public static int[] findDoub(String fileName) {
ArrayList<Integer> innt = new ArrayList<Integer>();
try {
File file = new File(fileName);
FileInputStream strem = new FileInputStream(file);
BufferedInputStream buff = new BufferedInputStream(strem);

int index = buff.read();
StringBuilder doubus = new StringBuilder("");
for (int i = 0; index != -1; i++) {
char a = (char) index;
if (i > 0) {
if (a != '|') {
doubus.append(a);
} else {
innt.add(Integer.valueOf(doubus.toString()));
doubus = new StringBuilder("");
}
}
index = buff.read();
}
buff.close();
strem.close();
buff = null;
strem = null;

} catch (IOException e) {
e.printStackTrace();
}
Runtime.getRuntime().gc();
int[] innnt = new int[innt.size()];
for (int i = 0; i < innnt.length; i++) {
innnt[i] = innt.get(i);
}
return innnt;
}

有几个地方使用了过多的内存,但除了返回的int[]之外,方法中的所有内容都是可垃圾收集的,因此您不应该有任何顾虑。

然而,如果你正在读取许多值,比如100000或更多,那么下面的建议将减少所需的内存占用。

在使用前预先设置ArrayList的大小可避免在其增长时重新分配:

int initialSize = 100000;
ArrayList<Integer> innt = new ArrayList<>(initialSize);

避免每个解析的Integer使用StringBuffer。由于int具有最大长度,您可以用final char[] doubus:替换

final char[] doubus = new char[Integer.toString(Integer.MAX_VALUE).length() + 2];
int dIndex = 0;
// ... Then append with:
if (a != '|') {
doubus[dIndex++] = a;
} else {
innt.add(Integer.valueOf(new String(doubus, 0, dIndex)));
dIndex=0;
}

Integer.valueOfArrayList<Integer>一起使用意味着将许多int值自动装箱为Integer,但最后提取为int。将ArrayList换成int[]并使用Integer.parseInt,因此结果始终是基元类型int意味着避免了许多内存转换:

int [] innt = new int[initialSize];
int iIndex = 0;
// Replace add with:
innt[iIndex++] = Integer.parseInt(new String(doubus, 0, dIndex));

把这些放在一起,你应该有相同的输出,希望更少的内存流失:

public static int[] findDoub(File file) throws IOException {
int initialSize = 100000; // Use suitable value
int [] innt = new int[initialSize];
int iIndex = 0;
try (BufferedInputStream buff = new BufferedInputStream(new FileInputStream(file))) {
int index = buff.read();
final char[] doubus = new char[Integer.toString(Integer.MAX_VALUE).length() + 2];
int dIndex = 0;
for (int i = 0; index != -1; i++) {
char a = (char) index;
if (i > 0) {
if (a != '|') {
doubus[dIndex++] = a;
} else {
// Grow int[] if needed:
if (iIndex == innt.length) {
innt = Arrays.copyOf(innt, innt.length + initialSize);
}
innt[iIndex++] = Integer.parseInt(new String(doubus, 0, dIndex));
dIndex=0;
}
}
index = buff.read();
}
}
// Return exact size int[] of current length:
return Arrays.copyOf(innt, iIndex);
}

您读取所有要innt的文件,直到函数结束。然后你把它复制到innnt。

两者都会导致ram的使用。

ram的使用也取决于文件大小。

您不需要复制innt,只需返回arraylist,它将提高ram的使用率。

你可以尝试拆分文件。

最新更新