为Android开发字典应用程序。 XML文件中有一个数据库。用DOM解析器解析它是相当大的(72MB)。尝试使用JDOM解析器解析它:
List<org.jdom2.Element> list = null;
try {
File db = new File(UnZip.DATABASE_PATH);
InputStream stream = new FileInputStream(db);
SAXBuilder builder = new SAXBuilder();
//HERE CODE IS GETTING STUCK
Document document = (Document) builder.build(stream);
org.jdom2.Element rootNode = document.getRootElement();
list = rootNode.getChildren(ENTRY_TAG);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (Element node : list) {
Log.d(LOG_TAG, node.getChildText(ENT_SEQ));
Log.d(LOG_TAG, node.getChildText(REB));
}
此代码提供OutOfMemory错误:
06-05 12:45:58.788:E / AndroidRuntime(10068):致命异常:主要 06-05 12:45:58.788:E / AndroidRuntime(10068): java.lang.OutOfMemoryError:[内存耗尽] 06-05 12:45:58.788: E / AndroidRuntime(10068):at dalvik.system.NativeStart.main(Native 方法)
我认为代码卡在这里:
Document document = (Document) builder.build(stream);
如何避免此错误并从整个XML文件(170000个条目)中找到所需的条目?
答案 0 :(得分:3)
JDOM,如DOM,XOM和所有其他内存中xml模型库,将代表内存中的整个XML文档。如果您认为大多数XML文档是单字节编码(UTF-8或ASCII),然后在Java / Android中转换为2字节字符,那么内存中的XML表示通常需要大约两倍的时间内存作为原始XML文档。
与其他人相比,JDOM非常尊重内存使用(我是维护者,我有偏见,但我在内存管理方面也尝试过非常努力)。
您可以尝试使用the SlimJDOMFactory作为文档构建的一部分,但这并不会为您节省多少钱。
所有内存中的XML模型都存在同样的问题,并且(针对不同的文档大小)存在于所有平台和系统配置上。
解决方案是:
答案 1 :(得分:1)
使用XmlPullParser类,如DarkDarker建议的那样。使用带有Reader的setInput()或带有InputStream和编码名称的setInput()(可能是&#34; UTF-8&#34;)。然后你可以使用解析器一次在文档中移动一个元素,随时构建列表。
所有DOM方法(包括JDOM,dom4j和其他方法)都是内存占用,因为它们在内存中构建整个文档表示。实际内存使用量通常至少是文档字节大小的4倍,字符串开销(每个字符两个字节)和文档每个组件的对象开销之间。