“OutOfMemoryError:超出GC开销限制”:使用java解析大型json文件

我尝试用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 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的单个元素并逐步将它们转换为对象。

在这里,您可以找到一篇很好的文章,解释如何使用jackson库。

你有两个选择:

  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 

但它不能成为一个永久的解决方案,因为您的文件将来可以增加