簡體   English   中英

“ OutOfMemoryError:超出了GC開銷限制”:使用java解析大型json文件

[英]“OutOfMemoryError: GC overhead limit exceeded”: parse large json file with java

我嘗試使用Java解析大型json文件(更多600Mo)。 我的json文件如下所示:

{
    "0" : {"link_id": "2381317", "overview": "mjklmklmklmklmk", "founded": "2015", "followers": "42", "type": "Gamer", "website": "http://www.google.com",  "name": "troll", "country": "United Kingdom", "sp": "Management Consulting" },
    "1" : {"link_id": "2381316", "overview": "mjklmklmklmklmk", "founded": "2015", "followers": "41", "type": "Gamer", "website": "http://www.google2.com",  "name": "troll2", "country": "United Kingdom", "sp": "Management Consulting" }
    [....]

    "345240" : {"link_id": "2381314", "overview": "mjklmklmklmklmk", "founded": "2015", "followers": "23", "type": "Gamer", "website": "http://www.google2.com",  "name": "troll2", "country": "United Kingdom", "sp": "Management Consulting" }
}

我的代碼如下所示:

public class dumpExtractor {

    private static final String filePath = "/home/troll/Documents/analyse/lol.json";

    public static void main(String[] args) {

    try {
        // read the json file
        FileReader reader = new FileReader(filePath);
        JSONParser jsonParser = new JSONParser();
        JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
        Iterator<JSONObject> iterator = jsonObject.values().iterator();

        while (iterator.hasNext()) {
        JSONObject jsonChildObject = iterator.next();
        System.out.println("==========================");
        String name = (String) jsonChildObject.get("name");
        System.out.println("Industry name: " + name);

        String type = (String) jsonChildObject.get("type");
        if (type != null && !type.isEmpty()) {
            System.out.println("type: " + type);
        }

        String sp = (String) jsonChildObject.get("sp");
        if (sp != null && !sp.isEmpty()) {
            System.out.println("sp: " + sp);
        }
        System.out.println("==========================");
        }
        System.out.println("done ! ");
    } catch (IOException ex) {
        ex.printStackTrace();
    } 
    }
}

我遇到了這個錯誤:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.HashMap.createEntry(HashMap.java:897)
    at java.util.HashMap.addEntry(HashMap.java:884)
    at java.util.HashMap.put(HashMap.java:505)
    at org.json.simple.parser.JSONParser.parse(Unknown Source)
    at org.json.simple.parser.JSONParser.parse(Unknown Source)

我該如何解決?

提前致謝。

如果必須讀取巨大的JSON文件,則無法在內存中保留所有信息。 擴展內存可能是1 Gb文件的解決方案。 如果明天的文件是2 Gb文件?

解決此問題的正確方法是使用流解析器逐元素解析json元素。 基本上,不需要讀取整個json並創建一個表示它的大對象,而是需要讀取json的單個元素並將它們逐步轉換為對象。

在這里,您會找到一篇不錯的文章,解釋了如何使用傑克遜庫進行操作。

您有兩種選擇:

  1. 通過指定-Xmx參數為Java程序分配更多內存,例如-Xmx1g分配1 Gb內存。
  2. 使用“流式” JSON解析器。 這將擴展到無限大的JSON文件。

json-simple具有流API。 請參閱https://code.google.com/p/json-simple/wiki/DecodingExamples#Example_5_-_Stoppable_SAX-like_content_handler

還有其他具有良好流解析器的庫,例如Jackson

通過設置環境變量來增加JVM堆空間:

SET _JAVA_OPTIONS = -Xms512m -Xmx1024m

但這不是永久性的解決方案,因為將來可以增加文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM