[英]Java - byte buffer Out Of Memory
Java的新功能,但是我已經能夠很快學到很多東西。 但是,仍然有許多方法使我難以理解。 我正在編寫一個Java程序,該程序將運行一堆文件並對其進行全面測試,以查看它們是否為有效的Level Pack文件。 多虧了Matt Olenik和他的GobFile類(僅用於提取文件),我得以找到一種很好的策略來獲取關卡包的重要部分及其單個地圖文件,從而快速確定各種細節。 但是,在37個文件(其中5個不是關卡包)上進行測試時,在測試35個文件后崩潰。 第35個文件是有效的級別包。 它給出的錯誤是:
線程“主”中的異常java.lang.OutOfMemoryError:Java堆空間
Iterator iter = itemList.keySet().iterator();
numJKLs = 0;
while (iter.hasNext()) {
String nextFile = (String) iter.next();
if (nextFile.startsWith("jkl\\")) {
System.out.println(((ItemInfo) itemList.get(nextFile)).length);
--> byte[] buffer = new byte[((ItemInfo) itemList.get(nextFile)).length];
gobRaf.seek(((ItemInfo) itemList.get(nextFile)).offset);
gobRaf.read(buffer, 0,
((ItemInfo) itemList.get(nextFile)).length);
String[] content = new String(buffer).toLowerCase().split(
"\n");
levels.add(numJKLs, new JKLFile(theFile, nextFile, content));
gametype = levels.get(numJKLs).getFileType();
progress.setProgText(nextFile);
buffer = null;
content = null;
numJKLs++;
}
}
箭頭顯示標記錯誤的位置。 “ JKLFile”類讀取這些重要部分的content
數組,但是(理論上)應該在完成后將其處置。 像這里,我設置content = null;
在JKLFile
只是為了確保它不存在。 如果您想知道它停下來的地圖文件有多大,那么它設法傳遞了一個17 Mb的地圖文件,但是這個文件只有5 Mb。
如您所見,這些JKLFile
對象保留在該對象( GobFile.java
)中,以便以后訪問,而GobFile
對象保留在另一個類中,以便以后訪問,直到更改目錄(尚未實現)為止。 但是這些對象不應太雜亂。 只是文件名和各種詳細信息的列表。
關於如何找出內存去向或哪些對象使用最多資源的任何建議? 當我從列表中單擊它們時,最好將詳細信息保留在內存中,而不必再次加載文件(最多2秒)。
/愛德華
現在,您正在為每個循環創建一個新的緩沖區。 根據您的垃圾回收,其中一些可能無法從內存中回收/釋放出來,然后耗盡。 您可以使用System.gc()
調用垃圾收集器,但不能保證它可以在任何給定時間實際運行。
使用-Xmx
和-Xms
參數調用程序時,可以在命令行上增加分配給JVM的內存。 另外,如果您不在32位Windows上,請確保您使用的是64位JVM,因為32位具有內存限制,而前者則沒有。 從命令行運行java -version
以查看當前系統JVM。
您可以將byte []緩沖區的聲明移到循環外( while
之上),以便在每次迭代時將其清除並重新使用。
Iterator iter = itemList.keySet().iterator();
numJKLs = 0;
byte[] buffer;
while (iter.hasNext()) {
...
buffer = new byte[] ...
...
}
您正在處理多少文件? 您是否真的需要將其中的每一項都添加到您的levels
變量中? 您能代替一些文件信息或統計信息嗎? 您的JVM當前已分配多少內存?
要在任何給定時間查看當前內存使用情況,您將需要在程序運行時對其進行調試。 查找如何為您選擇的IDE做到這一點,您將可以在程序的整個生命周期內跟蹤任何Object的當前狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.