android - java.lang.OutOfMemoryError on String.replace -
i have 1 text file contains 234 lines of string1@string2@string3.
kya@きゃ@キャ kyu@きゅ@キュ kyo@きょ@キョ sha@しゃ@シャ shu@しゅ@シュ ...so 234 lines
i writing converter converts word string2 or string3 word string1.
inputstream = context.getresources().openrawresource(r.raw.kanatoromaji); inputstreamreader isr = new inputstreamreader(is); bufferedreader reader = new bufferedreader(isr); string line; try { while ((line = reader.readline()) != null) { string[] parts = line.split("@"); string romaji = parts[0]; string hiragana=parts[1]; string katakana = parts[2]; if (hiragana!=null&&word.contains(hiragana)) { word = word.replace(hiragana, romaji);//in line getting outofmemory error } if (word.contains(katakana)) { word = word.replace(katakana, romaji); } } } catch (ioexception e) { e.printstacktrace(); }
i calling method many times (200k-300k times in 1 run). causing error: 07-24 00:52:32.859 10848-10848/net.joerichard.test e/androidruntime﹕ fatal
exception: main java.lang.outofmemoryerror @ java.lang.abstractstringbuilder.enlargebuffer(abstractstringbuilder.java:94) @ java.lang.abstractstringbuilder.append0(abstractstringbuilder.java:132) @ java.lang.stringbuilder.append(stringbuilder.java:124) @ java.lang.string.replace(string.java:1367) @ net.joerichard.test.converter.kanatoromaji(converter.java:32) @ net.joerichard.test.mainactivity.migratekanakanji(mainactivity.java:222) @ net.joerichard.test.mainactivity.access$700(mainactivity.java:29) @ net.joerichard.test.mainactivity$10.onclick(mainactivity.java:131) @ android.view.view.performclick(view.java:4240) @ android.view.view$performclick.run(view.java:17721) @ android.os.handler.handlecallback(handler.java:730) @ android.os.handler.dispatchmessage(handler.java:92) @ android.os.looper.loop(looper.java:137) @ android.app.activitythread.main(activitythread.java:5103) @ java.lang.reflect.method.invokenative(native method) @ java.lang.reflect.method.invoke(method.java:525) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:737) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:553) @ dalvik.system.nativestart.main(native method)
what problem in code? how solve it?
update:
according jfpicard's answer, converted string word stringbuilder sbword. tried replace string2 , string3 using stringbuilder. never replaced stringbuilder before. search in google , found solution replace stringbuilder parts. code looks this:
public static string kanatoromaji(context context, string word) { string kana = word; stringbuilder sbword = new stringbuilder(word); inputstream = context.getresources().openrawresource(r.raw.kanatoromaji); inputstreamreader isr = new inputstreamreader(is); bufferedreader reader = new bufferedreader(isr); string line; try { while ((line = reader.readline()) != null) { string[] parts = line.split("@"); string romaji = parts[0]; string hiragana=parts[1]; string katakana = parts[2]; if (hiragana!=null&&word.contains(hiragana)) { sbword = replaceall(sbword, hiragana, romaji);//in line getting outofmemory error } if (word.contains(katakana)) { sbword = replaceall(sbword, katakana, romaji); } } } catch (ioexception e) { e.printstacktrace(); } char[] chars = kana.tochararray(); (char character: chars) { if(sbword.tostring().contains(string.valueof(character))) { new mylog(kana+":"+sbword.tostring()); break; } } return word; }
method replace stringbuilder parts:
public static stringbuilder replaceall(stringbuilder builder, string from, string to) { int index = builder.indexof(from); while (index != -1) { builder.replace(index, index + from.length(), to); index += to.length(); // move end of replacement index = builder.indexof(from, index); } return builder; }
now getting error: 07-24 01:23:52.890 13512-13512/net.joerichard.test e/androidruntime﹕ fatal
exception: main java.lang.outofmemoryerror @ java.lang.abstractstringbuilder.move(abstractstringbuilder.java:397) @ java.lang.abstractstringbuilder.insert0(abstractstringbuilder.java:356) @ java.lang.abstractstringbuilder.replace0(abstractstringbuilder.java:442) @ java.lang.stringbuilder.replace(stringbuilder.java:637) @ net.joerichard.test.converter.replaceall(converter.java:65) @ net.joerichard.test.converter.kanatoromaji(converter.java:33) @ net.joerichard.test.mainactivity.migratekanakanji(mainactivity.java:222) @ net.joerichard.test.mainactivity.access$700(mainactivity.java:29) @ net.joerichard.test.mainactivity$10.onclick(mainactivity.java:131) @ android.view.view.performclick(view.java:4240) @ android.view.view$performclick.run(view.java:17721) @ android.os.handler.handlecallback(handler.java:730) @ android.os.handler.dispatchmessage(handler.java:92) @ android.os.looper.loop(looper.java:137) @ android.app.activitythread.main(activitythread.java:5103) @ java.lang.reflect.method.invokenative(native method) @ java.lang.reflect.method.invoke(method.java:525) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:737) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:553) @ dalvik.system.nativestart.main(native method)
what in situation?
i think have idea.
this line word = word.replace(hiragana, romaji);
and 1 word = word.replace(katakana, romaji);
create new string each time. string immutable consume memory. lot in case.
try use stringbuilder instead.
Comments
Post a Comment