我正在从数据库中读取3列值(大约5万条记录),然后尝试在Json文件中搜索此值。 Json文件包含200万个Json对象。 我尝试了以下方法。
方法1。
JSONArray json = readJson(Constants.jsonFilePath);
private JSONArray readJson(String jsonFilePath) {
String content = null;
File file = new File(Constants.jsonFilePath);
try {
content = FileUtils.readFileToString(file, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
return new JSONArray(content);
}
然后线性搜索所需的字段值
我针对大小为150 MB的文件测试了上面的代码,效果很好。但是,当我针对大小为2 gb的文件进行测试时,却收到OutOfHeapMemory错误。
方法2:
然后,我尝试一次从文件中读取100 000个Json对象,然后检查所需的字段值,但是过程非常缓慢。
我正在使用org.json库。 有什么更好的方法来解决上述问题?
答案 0 :(得分:4)
当然,它会很慢,它包含大量数据。 将其拆分为更多可管理的块是您唯一可以做的事情,并且您必须将对性能的影响作为经营的成本,因为它根本无法容纳在内存中。
当然,您可以告诉JVM声明4GB的RAM,并希望它足够了,但是处理该数量的数据仍然需要花费很多时间。
留下了一个问题,为什么您要尝试处理这么大的单个JSON对象,所以存储大数据的方法要比处理CPU和RAM少得多的方法好得多。 我想到了数据库,可以使用SQL或类似的查询语言很好地进行搜索。
在这一点上,您不仅正在运行合理的JVM限制,而且正在运行操作系统本身。
答案 1 :(得分:2)
您应该使用流式JSON解析器,而不是读取整个文件。 这将很慢,但是可以控制。 查看Jackson Streaming API,了解如何实现这一目标。
这确实意味着您将不得不处理JSON对象的低级处理,但是应该比将所有JSON加载到内存中更快。
此处link是使用Streaming API的地方。
请注意,GSON也具有类似的流API。
答案 2 :(得分:0)
您是否尝试过创建自己的JSON解析器(针对特定的JSON obj)?由于您已经知道这种情况下的JSON格式。然后只需线性解析单个obj(您可以使用readLine()直到第一个打开的'{')关闭'}'为止,然后与搜索值进行比较。 :D 您还可以使用多线程方法来减少时间。
这只是个主意,我仍然不清楚您的JSON文件是什么样子。