Java 读取多个资源时发生OutOfMemoryError
我有一个函数,可以读取资产文件并将其内容存储在数组中。这是密码Java 读取多个资源时发生OutOfMemoryError,java,android,file-io,out-of-memory,android-assets,Java,Android,File Io,Out Of Memory,Android Assets,我有一个函数,可以读取资产文件并将其内容存储在数组中。这是密码 private List<String> infinitivesDB; private List<String> formsDB; private void getDB(String lang, String type) { while(true) { try { String infinitivesDB = getString
private List<String> infinitivesDB;
private List<String> formsDB;
private void getDB(String lang, String type)
{
while(true)
{
try {
String infinitivesDB = getStringFromAssetFile(this, "inf.txt");
this.infinitivesDB = new LinkedList(Arrays.asList(infinitivesDB.split("\n")));
break; //would be needed if it was reachable
} catch (IOException e) {
e.printStackTrace();
}
}
while(true)
{
try {
String formsDB = getStringFromAssetFile(this, "forms.txt");//EXCEPTION HERE?
this.formsDB = new LinkedList(Arrays.asList(formsDB.split("\n")));
break; //would be needed if it was reachable
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是,如果我尝试只读取一个文件(通过注释其中一个while循环及其内容),无论我选择哪个文件,它都可以正常工作。如果我尝试在两个循环中读取“inf.txt”(较小)并存储在这些不同的数组中,它也可以正常工作
此外,如果我简单地切换“whiles”,从而在较小的文件之前读取较大的文件,它也可以工作
我想知道为什么会这样。另外,如果两个资产文件都很大,我如何读取它们?我试图在两个循环中读取“forms.txt”(更大),但它引发了相同的错误(我真的希望如此)。导致此错误的原因是您试图从一个3.5 mb的文件中加载大量字符串数据。这方面的快速解决方案是 您可以使用android:largeHeap=“true”请求更大的堆大小,但这在任何预蜂窝设备上都不起作用。在2.3之前的设备上,您可以使用VMRuntime类,但这在姜饼和更高版本上不起作用 拥有尽可能大的限制的唯一方法是通过NDK执行内存密集型任务,因为NDK不像SDK那样施加内存限制 或者,您可以只加载当前视图中的模型部分,并根据需要加载其余部分,同时从内存中删除未使用的部分。但是,这可能不可能,具体取决于您的应用程序 在API级别11+上运行的应用程序可以在清单中的元素上使用android:largeHeap=“true”来请求比正常堆大的堆大小,ActivityManager上的getLargeMemoryClass()将告诉您堆有多大。然而: 这仅适用于API级别11+(即蜂窝状和更高级别) 无法保证这个大堆会有多大 用户将感知到您的大堆请求,因为它将强制其其他应用程序退出RAM,并终止其他应用程序的进程以释放系统RAM供您的大堆使用 由于#3,以及我预计android:largeHeap将被滥用的事实,对它的支持可能会在将来被放弃,或者用户可能会在安装时被警告(例如,您需要为它申请特殊许可)
目前,这项功能的文档很少我可以在这里看到一些糟糕的设计决策。最重要的是:如果您需要一个文件作为字符串列表,为什么不直接这样读呢 使用扫描器读取流,扫描器本身不是必需的。其他io类允许您读取行而不会出现这种复杂情况 looong字符串被拆分成一个大数组,最终生成列表。因此,内存中的文件至少有三份 LinedList可以高效地增长,但这里不需要它。ArrayList更节省空间
getStringFromAssetFile必须重新设计。我怀疑错误来自此代码。请查看方法中的更多问题
getStringFromAssetFile
您可以发布它的代码吗。
07-27 02:40:13.399: E/AndroidRuntime(2017): FATAL EXCEPTION: main
07-27 02:40:13.399: E/AndroidRuntime(2017): Process: com.highstaker.formdictionary, PID: 2017
07-27 02:40:13.399: E/AndroidRuntime(2017): java.lang.OutOfMemoryError
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.util.Scanner.expandBuffer(Scanner.java:2067)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.util.Scanner.readMore(Scanner.java:2031)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.util.Scanner.findDelimiterAfter(Scanner.java:2009)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.util.Scanner.setTokenRegion(Scanner.java:1923)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.util.Scanner.hasNext(Scanner.java:541)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.util.Scanner.hasNext(Scanner.java:519)
07-27 02:40:13.399: E/AndroidRuntime(2017): at com.highstaker.formdictionary.MainActivity.convertStreamToString(MainActivity.java:411)
07-27 02:40:13.399: E/AndroidRuntime(2017): at com.highstaker.formdictionary.MainActivity.getStringFromAssetFile(MainActivity.java:404)
07-27 02:40:13.399: E/AndroidRuntime(2017): at com.highstaker.formdictionary.MainActivity.getDB(MainActivity.java:389)
07-27 02:40:13.399: E/AndroidRuntime(2017): at com.highstaker.formdictionary.MainActivity.onCreate(MainActivity.java:50)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.Activity.performCreate(Activity.java:5243)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.ActivityThread.access$700(ActivityThread.java:135)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.os.Handler.dispatchMessage(Handler.java:102)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.os.Looper.loop(Looper.java:137)
07-27 02:40:13.399: E/AndroidRuntime(2017): at android.app.ActivityThread.main(ActivityThread.java:4998)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.lang.reflect.Method.invokeNative(Native Method)
07-27 02:40:13.399: E/AndroidRuntime(2017): at java.lang.reflect.Method.invoke(Method.java:515)
07-27 02:40:13.399: E/AndroidRuntime(2017): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
07-27 02:40:13.399: E/AndroidRuntime(2017): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
07-27 02:40:13.399: E/AndroidRuntime(2017): at dalvik.system.NativeStart.main(Native Method)
07-27 02:40:15.179: I/Process(2017): Sending signal. PID: 2017 SIG: 9