Ich mache tief lernen neuronalen Netzentwicklung, mit dem MNIST-Datensatz zum Testen. Der Trainingssatz besteht aus 60.000 Sequenzen mit jeweils 784 Eingabewerten mit doppelter Genauigkeit. Der Prozess des Lesens dieser Daten aus der Datei in ein Array in Java verursacht irgendwie einen Arbeitsspeicher-Overhead von ungefähr 4 GB, der während des Laufs des Programms zugeordnet bleibt. Dieser Overhead ist zusätzlich zu den 60000 · 784 · 8 = 376 MB, die für das Array mit doppelter Genauigkeit selbst zugewiesen sind. Es scheint wahrscheinlich, dass dieser Overhead auftritt, weil Java eine vollständige Kopie der Datei in einem Zusatz zu dem numerischen Array speichert, aber dies ist möglicherweise Scanner-Overhead.Großer Speicheraufwand beim Lesen einer großen Datendatei in Java
Laut einer Quelle wird beim Lesen der Datei als Stream vermieden, dass die gesamte Datei im Speicher abgelegt wird. Allerdings habe ich immer noch dieses Problem mit einem Stream gelesen. Ich verwende Java 8 mit Intellij 2016.2.4. Dies ist der Strom-Lesecode:
FileInputStream inputStream = null;
Scanner fileScan = null;
String line;
String[] numbersAsStrings;
totalTrainingSequenceArray = new double[60000][784];
try {
inputStream = new FileInputStream(m_sequenceFile);
fileScan = new Scanner(inputStream, "UTF-8");
int sequenceNum = 0;
line = fileScan.nextLine();//Read and discard the first line.
while (fileScan.hasNextLine()) {
line = fileScan.nextLine();
numbersAsStrings = line.split("\\s+"); //Split the line into an array of strings using any whitespace delimiter.
for (int inputPosition = 0; inputPosition < m_numInputs; inputPosition++) {
totalTrainingSequenceArray[sequenceNum][inputPosition] = Double.parseDouble(numbersAsStrings[inputPosition]);
}
sequenceNum++;
}
if (fileScan.ioException() != null) {//Handle fileScan exception
throw fileScan.ioException();
}
} catch (IOException e) {//Handle the inputstream exception
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileScan != null) {
fileScan.close();
}
}
Ich habe versucht, den Strom und den Scanner auf null, nachdem die Leseeinstellung und Aufruf System.gc(), aber das tut nichts. Ist dies ein Problem mit dem Scanner-Overhead? Was wäre der einfachste Weg, diese große Datei zu lesen, ohne großen permanenten Overhead zu verursachen? Danke für jede Eingabe.
Wie messen Sie die Speichernutzung? – NPE
Wenn Sie Java 8 verwenden, können Sie von der 'Files.lines()' Methode profitieren. – assylias
NPE - Ich messe Speicher mit Windows Task Manager. –