“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库。
你有两个选择:
- 通过指定
-Xmx
参数为Java程序提供更多内存,例如-Xmx1g
为其提供1 Gb内存。 - 使用“流式”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
但它不能成为一个永久的解决方案,因为您的文件将来可以增加
- Guava MultiMap和ConcurrentModificationException
- 在Play 2.0 Framework模板引擎中进行计算
- 使用Maven将文件转换为UNIX格式
- 如何使用Java中的计时器在特定时间内运行作业?
- 如何保护我的java Web应用程序?
- 将generics类@MappedSuperclass应用为targetEntity.Error:模型上的@ManyToOne.Unit.parent引用未知实体:models.GenericHierarchic
- 如何运行PING命令并获取ping主机摘要?
- 创建了多少个Java字符串?
- 通过Java 8中的方法引用调用toString