Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 读取多个资源时发生OutOfMemoryError_Java_Android_File Io_Out Of Memory_Android Assets - Fatal编程技术网

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