Я пытаюсь прочитать текстовый файл размером 816 КБ (70 000 строк) в моем приложении для Android, которое находится в папке res / raw. Это соответствующий фрагмент кода:
InputStream raw = context.getResources().openRawResource(R.raw.alpha);
InputStreamReader inputreader = new InputStreamReader(raw);
BufferedReader r = new BufferedReader(inputreader);
String line;
int j = 0;
while ((line = r.readLine()) != null && j < 90000){
theTrie.insert(line);
j++;
}
«Контекст» задается с помощью параметра: Main.readDatabase (getApplication ());
Эта версия аварийно завершает работу со следующим журналом:
10-04 21:14:26.096: INFO/dalvikvm(1327): | group="main" sCount=0 dsCount=0 obj=0x4001f1a8 self=0xce48
10-04 21:14:26.096: INFO/dalvikvm(1327): | sysTid=1327 nice=0 sched=0/0 cgrp=default handle=-1345006528
10-04 21:14:26.096: INFO/dalvikvm(1327): | schedstat=( 3112456663 436561269 431 )
10-04 21:14:26.096: INFO/dalvikvm(1327): at java.lang.Throwable.nativeFillInStackTrace(Native Method)
10-04 21:14:26.096: INFO/dalvikvm(1327): at java.lang.Throwable.fillInStackTrace(Throwable.java:135)
10-04 21:14:26.096: INFO/dalvikvm(1327): at java.lang.Throwable.<init>(Throwable.java:74)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.lang.Error.<init>(Error.java:38)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.lang.VirtualMachineError.<init>(VirtualMachineError.java:36)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:34)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.util.HashMap.makeTable(HashMap.java:-1)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.util.HashMap.<init>(HashMap.java:162)
10-04 21:14:26.106: INFO/dalvikvm(1327): at snappy.keyboard.TrieNode.<init>(TrieNode.java:21)
10-04 21:14:26.106: INFO/dalvikvm(1327): at snappy.keyboard.Trie.insert(Trie.java:27)
10-04 21:14:26.106: INFO/dalvikvm(1327): at snappy.keyboard.Main.readDatabase(Main.java:356)
10-04 21:14:26.106: INFO/dalvikvm(1327): at snappy.keyboard.SoftKeyboard.onCreate(SoftKeyboard.java:89)
10-04 21:14:26.106: INFO/dalvikvm(1327): at android.app.ActivityThread.handleCreateService(ActivityThread.java:1920)
10-04 21:14:26.106: INFO/dalvikvm(1327): at android.app.ActivityThread.access$2500(ActivityThread.java:117)
10-04 21:14:26.106: INFO/dalvikvm(1327): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:982)
10-04 21:14:26.106: INFO/dalvikvm(1327): at android.os.Handler.dispatchMessage(Handler.java:99)
10-04 21:14:26.106: INFO/dalvikvm(1327): at android.os.Looper.loop(Looper.java:123)
10-04 21:14:26.106: INFO/dalvikvm(1327): at android.app.ActivityThread.main(ActivityThread.java:3647)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.lang.reflect.Method.invokeNative(Native Method)
10-04 21:14:26.106: INFO/dalvikvm(1327): at java.lang.reflect.Method.invoke(Method.java:507)
10-04 21:14:26.106: INFO/dalvikvm(1327): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
10-04 21:14:26.106: INFO/dalvikvm(1327): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
10-04 21:14:26.106: INFO/dalvikvm(1327): at dalvik.system.NativeStart.main(Native Method)
10-04 21:14:26.196: WARN/dalvikvm(1327): Exception thrown (Ljava/lang/OutOfMemoryError;) while throwing internal exception (Ljava/lang/OutOfMemoryError;)
10-04 21:14:26.326: INFO/dalvikvm-heap(1327): Clamp target GC heap from 25.881MB to 24.000MB
10-04 21:14:26.326: DEBUG/dalvikvm(1327): GC_CONCURRENT freed <1K, 13% free 20224K/22983K, external 1625K/2137K, paused 2ms+3ms
10-04 21:14:26.446: INFO/dalvikvm-heap(1327): Clamp target GC heap from 25.856MB to 24.000MB
10-04 21:14:26.446: DEBUG/dalvikvm(1327): GC_FOR_MALLOC freed 25K, 13% free 20198K/22983K, external 1625K/2137K, paused 123ms
10-04 21:14:26.446: DEBUG/AndroidRuntime(1327): Shutting down VM
Если я не запускаю этот код (слегка измененный из-за чтения файлов) в эмуляторе, но в обычном Java-приложении он работает без проблем, но на Android, похоже, есть утечка памяти? У кого-нибудь есть идеи, в чем может быть проблема?
Даже если я удалю строку "theTrie.insert (line);" так что цикл while (почти) пуст, приложению требуется 2,1 секунды для «повторного выравнивания» 800 кб. Это не может быть нормальным, верно? Где моя ошибка?
Заранее спасибо!
Обновление:
Я записал в кучу файл с DDMS и проанализировал его с помощью MAT. Это говорит: класс [в вопросе], загруженный "dalvik.system.PathClassLoader @ 0x4051d5e8", занимает 23.951.808 (91,76%) байтов. Память накапливается в одном экземпляре "java.util.HashMap $ HashMapEntry []", загруженном "".
Гистограмма перечисляет java.util.HashMap $ HashMapEntry [], java.util.HashMap и java.util.HashMap $ HashMapEntry в качестве трех объектов с самой большой мелкой кучей.
Вот мой код, касающийся использования хэш-карты (в классе, определяющем узел дерева):
public Map<Character, TrieNode> children;
public TrieNode(char letter) {
this.letter = letter;
children = new HashMap<Character, TrieNode>(26);
}
Что вызывает утечку памяти?