"OutOfMemoryError: GC overhead limit exceeded": parse large json file with java
"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)
我该如何解决?
提前致谢。
您有两个选择:
- 通过指定
-Xmx
参数为 Java 程序提供更多内存,例如-Xmx1g
给它 1 Gb 的内存。
- 使用 "streaming" JSON 解析器。这将扩展到无限大 JSON 个文件。
json-simple has a streaming API. See https://code.google.com/p/json-simple/wiki/DecodingExamples#Example_5_-_Stoppable_SAX-like_content_handler
还有其他库具有良好的流解析器,例如Jackson.
如果您必须阅读巨大的 JSON 文件,您无法在内存中保留所有信息。
扩展内存可以解决 1 Gb 文件的问题。如果明天的文件是 2 Gb 文件?
解决此问题的正确方法是使用流式解析器逐个元素地解析 json。基本上不需要将整个 json 加载到内存中并创建一个表示它的整个大对象,您需要读取 json 的单个元素并将它们逐步转换为对象。
Here 你找到了一篇解释如何使用 jackson 库的好文章。
通过设置环境变量增加 JVM 堆 space :
SET _JAVA_OPTIONS = -Xms512m -Xmx1024m
但这不是永久性的解决方案,因为您的文件将来可能会增加
我尝试用 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)
我该如何解决?
提前致谢。
您有两个选择:
- 通过指定
-Xmx
参数为 Java 程序提供更多内存,例如-Xmx1g
给它 1 Gb 的内存。 - 使用 "streaming" JSON 解析器。这将扩展到无限大 JSON 个文件。
json-simple has a streaming API. See https://code.google.com/p/json-simple/wiki/DecodingExamples#Example_5_-_Stoppable_SAX-like_content_handler
还有其他库具有良好的流解析器,例如Jackson.
如果您必须阅读巨大的 JSON 文件,您无法在内存中保留所有信息。 扩展内存可以解决 1 Gb 文件的问题。如果明天的文件是 2 Gb 文件?
解决此问题的正确方法是使用流式解析器逐个元素地解析 json。基本上不需要将整个 json 加载到内存中并创建一个表示它的整个大对象,您需要读取 json 的单个元素并将它们逐步转换为对象。
Here 你找到了一篇解释如何使用 jackson 库的好文章。
通过设置环境变量增加 JVM 堆 space :
SET _JAVA_OPTIONS = -Xms512m -Xmx1024m
但这不是永久性的解决方案,因为您的文件将来可能会增加