我用Java NIO读了大约7gb的XML文件(每个〜15kb)。并在以后使用JAXB对其进行转换。 处理完所有文件(〜12分钟)并正确关闭应用程序后,我对Windows 10机器显示的〜16GB内存消耗感到好奇。
RamMap(Sysinternals)显示,映射文件消耗了大多数文件。实际上,我的系统似乎将所有(?)处理过的文件保存在内存中。但是,此内存使用情况在Windows资源监视器可以显示给我的任何进程下列出。
但是,如果我重新启动应用程序(通过Eclipse),可以看到我的Collection仍处于相同的Object-Adress。因此,第二次运行该应用程序会将瓶颈从HDD更改为CPU。
仅当我重新启动系统时才释放内存。注销不会这样做。 由于我想对在我的计算机上使用Java进行IO的不同方法进行基准测试,因此令人不安。
我的管道在完成下一个文件夹之前先处理一个文件夹。
getAllFolders
收集我要处理的文件夹(〜300)getAllFilesInFolder
收集其下的所有文件(〜2ká15kb)(递归)unmarshal
由getAllFilesInFolder
并行流收集的所有文件(〜2k)List<MyXml>
转换为单个MyXml
marshal
MyXml
以下方法处理用于解组的List<Path>
的创建。
// Method returns all Folders inside the entryPath
public List<Path> getAllFolders(Path entryPath) {
List<Path> folderList = Collections.synchronizedList(new ArrayList<Path>());
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(entryPath)) {
for (Path path : directoryStream) {
if (Files.isDirectory(path)) {
folderList.add(path);
}
}
}
return folderList;
}
// Method returns all regular Files inside the path
public List<Path> getAllFilesInFolder(Path path){
try (Stream<Path> files = Files.walk(path).filter(Files::isRegularFile)) {
return files.collect(Collectors.toList());
}
return null;
}
单独运行这些文件大约需要2分钟,这似乎不是mmap文件很大的原因。
根源似乎在编组/解组:
public class XmlMarshaller {
private JAXBContext jaxbContext;
private XmlMarshaller() {
jaxbContext = JAXBContext.newInstance(MyXml.class);
}
private static class LazyHolder {
private static final XmlMarshaller INSTANCE = new XmlMarshaller();
}
public static XmlMarshaller getInstance() {
return LazyHolder.INSTANCE;
}
public void marshal(MyXml xml, Path output) {
try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(output), StandardCharsets.UTF_8)) {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, StandardCharsets.UTF_8.toString());
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(xml, osw);
}
}
public MyXml unmarshal(Path file) {
MyXml xml = null;
try (InputStreamReader isr = new InputStreamReader(Files.newInputStream(file), StandardCharsets.UTF_8)) {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
xml = (MyXml) unmarshaller
.unmarshal(isr);
}
return xml;
}
}
我删除了catch(){...}
语句以提高可读性。
我正确处理输入/输出流吗?我可以泄漏资源吗?还是Windows 10在这里进行了优化?