Android:java.lang.OutOfMemoryError:无法分配带有2097152个空闲字节的23970828字节分配和2MB直到OOM

and*_*Tag 317 android android-bitmap

我想在已存储的SD卡中显示ImageView中Bitmap图像.运行后我的应用程序崩溃并导致OutOfMemoryError错误:

(java.lang.OutOfMemoryError:无法分配带有2097152个空闲字节的23970828字节分配和2MB直到OOM)

我不知道或为什么它的内存不足.我认为我的图像尺寸非常大,所以我试图改变它.

Iterator<String> it = imageArray.iterator();
while (it.hasNext()) {
  Object element = it.next();
  String objElement = element.toString();
  Log.e("objElement ", " = " + objElement);
  final ImageView imageView = new ImageView (getContext());
  final ProgressBar pBar = new ProgressBar(getContext(), null, 
                                           android.R.attr.progressBarStyleSmall);
  imageView.setTag(it);
  pBar.setTag(it);

  imageView.setImageResource(R.drawable.img_placeholder);
  pBar.setVisibility(View.VISIBLE);

  if (objElement.endsWith(mp3_Pattern)) {
     Log.e("Mp3 ", " ends with ");
     pBar.setVisibility(View.GONE);
     imageView.setImageResource(R.drawable.audio_control);
  }
  if (objElement.endsWith(png_Pattern)) {
     Bitmap bitmap = BitmapFactory.decodeFile(objElement);
     int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
     int x = (bitmap.getWidth() - size) / 2;
     int y = (bitmap.getHeight() - size) / 2;
     Bitmap bitmap_Resul = Bitmap.createBitmap(bitmap, x, y, size, size);
     Log.e("bitmap_Resul "," = "+ bitmap_Resul);

     if (bitmap_Resul != bitmap) {
        bitmap.recycle();
     }
     imageView.setImageBitmap(bitmap_Resul);
     Log.e("png_Pattern ", " ends with ");
     Log.e(" bitmap "," = " + bitmap);
  }

  holder.linearLayout.addView(imageView);
  holder.linearLayout.addView(pBar);
Run Code Online (Sandbox Code Playgroud)

日志猫信息:

08-27 14:11:15.307    1857-1857/? E/AndroidRuntime? FATAL EXCEPTION: main
    Process: com.example.tazeen.classnkk, PID: 1857
    java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM
            at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
            at android.graphics.Bitmap.nativeCreate(Native Method)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:812)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:789)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:709)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:634)
            at com.example.tazeen.classnkk.AllPosts_Page$MyListAdapter.getView(AllPosts_Page.java:357)
            at android.widget.AbsListView.obtainView(AbsListView.java:2347)
            at android.widget.ListView.makeAndAddView(ListView.java:1864)
            at android.widget.ListView.fillDown(ListView.java:698)
            at android.widget.ListView.fillFromTop(ListView.java:759)
            at android.widget.ListView.layoutChildren(ListView.java:1659)
            at android.widget.AbsListView.onLayout(AbsListView.java:2151)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
            at android.view.Choreographer.doCallbacks(Choreographer.java:580)
            at android.view.Choreographer.doFrame(Choreographer.java:550)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Run Code Online (Sandbox Code Playgroud)

Kin*_*ses 473

OutOfMemoryError是android中最常见的问题,尤其是在处理位图时.当由于内存空间不足而无法分配对象时,Java虚拟机(JVM)会抛出此错误,并且垃圾收集器也无法释放一些空间.

正如Aleksey所提到的,您可以在清单文件中添加以下实体android:hardwareAccelerated="false",android:largeHeap="true"它适用于某些环境.

<application
    android:allowBackup="true"
    android:hardwareAccelerated="false"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
Run Code Online (Sandbox Code Playgroud)

你应该明确地阅读一些Androids Developer概念,特别是在这里:有效地显示位图

阅读所有5个主题并重新编写代码.如果它仍然不起作用,我们将很高兴看到您对教程材料的错误.

这里是SOF中这些类型错误的一些可能答案

Android:BitmapFactory.decodeStream()内存不足,带有2MB空闲堆的400KB文件

如何在Android中解决java.lang.OutOfMemoryError问题

Android:java.lang.OutOfMemoryError

java.lang.OutOfMemoryError

OutOfMemoryError的解决方案:位图大小超过VM预算

编辑:来自@cjnash的评论

对于那些在添加此行后仍然崩溃的人,请尝试将您的图片粘贴到res/drawable-xhdpi /文件夹而不是res/drawable /,它可能会解决您的问题.

  • android:hardwareAccelerated ="false"冻结你的应用程序 (7认同)
  • 为什么你会建议android:hardwareAccelerated ="false?它有什么好处? (5认同)
  • 添加此功能后,应用导航变得非常慢. (4认同)
  • 设置 **android:hardwareAccelerated="false"**,停止了我的应用程序的许多动画,例如阴影和高度。 (4认同)
  • 对于添加此行后仍然崩溃的任何人,请尝试将图像粘贴到 res/drawable-xhdpi/ 文件夹而不是 res/drawable/ 中,它可能会解决您的问题。 (3认同)
  • android:hardwareAccelerated="false" 、 android:largeHeap="true" 是最佳实践还是某种黑客行为? (2认同)

小智 82

您是否尝试将此添加到应用程序下的清单中? android:largeHeap="true"

像这样

  <application
      android:name=".ParaseApplication"
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme"
      android:largeHeap="true" >
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个android:largeHeap ="true"但得到同样的错误 (15认同)

Ale*_*nko 26

实际上你可以在你的清单中添加这些行android:hardwareAccelerated="false",android:largeHeap="true"它适用于某些情况,但要注意代码的其他部分可以与此争论.

<application
    android:allowBackup="true"
    android:hardwareAccelerated="false"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
Run Code Online (Sandbox Code Playgroud)

  • 使用Bitmap.createBitmap时,它没有工作,它崩溃了同样的错误 (2认同)
  • **android:hardwareAccelerated="false"** 的目的是什么? (2认同)

pet*_*urg 22

对我来说,问题是我的.png文件被解压缩为内存中非常大的位图,因为图像具有非常大的尺寸(即使文件大小很小).

所以修复就是简单地调整图像大小:)

  • 这是正确的解决方案,因为我首先尝试了上述解决方案,但是在应用`android:hardwareAccelerated="false"`后,一些动画如布局阴影不起作用。但是调整大小后,所有问题都解决了,谢谢!+1 这个提示! (4认同)

Aks*_*rla 22

这应该工作

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 8;

 mBitmapSampled = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
Run Code Online (Sandbox Code Playgroud)


小智 10

在设置为ImageView之前调整图像大小,如下所示:

Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);
Run Code Online (Sandbox Code Playgroud)

其中size是ImageView的实际大小.您可以通过测量来达到尺寸:

imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
Run Code Online (Sandbox Code Playgroud)

并使用下一大小imageView.getMeasuredWidth()imageView.getMeasuredHeight()scaling.


Mah*_*bar 9

使用Glide Library和Override尺寸减小尺寸;

Glide.with(mContext).load(imgID).asBitmap().override(1080, 600).into(mImageView);
Run Code Online (Sandbox Code Playgroud)


Sai*_*i N 9

我得到以下错误

"E/art: Throwing OutOfMemoryError "未能分配 47251468 字节的分配,其中有 16777120 个可用字节和 23MB,直到 OOM"

加入后,android:largeHeap="true"AndroidManifest.xml中然后我摆脱所有的错误

<application
    android:allowBackup="true"
    android:icon="@mipmap/guruji"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:largeHeap="true"
    android:theme="@style/AppTheme">
Run Code Online (Sandbox Code Playgroud)


max*_*pan 7

我已经通过将图像调整为较小的尺寸来解决这个问题。我正在使用 xamarin 形式。减小 PNG 图像的大小解决了这个问题。


小智 7

问题:无法分配 37748748 字节的分配,其中有 16777120 个空闲字节和 17MB,直到 OOM

解决方案:1.打开您的清单文件 2.在应用程序标签中添加以下两行

 android:hardwareAccelerated="false"
 android:largeHeap="true"
Run Code Online (Sandbox Code Playgroud)

例子 :

 <application
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:largeHeap="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
Run Code Online (Sandbox Code Playgroud)


And*_*der 6

我发现“drawable”文件夹中的图像将在高清手机上转换为更大的图像。例如,200k 图像将被重新采样为更高的分辨率,如 800k 或 32000k。我必须自己发现这一点,迄今为止还没有看到有关此堆内存陷阱的文档。为了防止这种情况,我将所有内容都放在 drawable-nodpi 文件夹中(除了在基于特定设备堆的 BitmapFactory 中使用“选项”之外)。我不能让我的应用程序的大小因多个可绘制文件夹而膨胀,尤其是现在屏幕定义的范围如此之大。棘手的是工作室现在并没有在项目视图中专门指示“drawable-nodpi”文件夹,它只显示一个“drawable”文件夹。如果你不小心,当你把一张图片放到工作室的这个文件夹中时,它不会

Careful here 'backgroundtest' did not actually go to drawable-nodpi and will 
be resampled higher, such as 4x or 16x of the original dimensions for high def screens.
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

请务必单击对话框中的 nodpi 文件夹,因为项目视图不会像以前那样单独向您显示所有可绘制文件夹,因此不会立即明显看出它出错了。在我很久以前删除它之后,工作室在某个时候为我重新创建了香草“可绘制”:

在此处输入图片说明


Opr*_*day 6

如果 android:largeHeap="true" 不适合你那么

1:

图像压缩。我正在使用这个网站

2:

将图像转换为 mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi。我正在使用这个 网站

不要删除 android:largeHeap="true"!


Hos*_*ini 5

这对我有用:只需将图像从 drawable 文件夹移动到 drawable-hdpi。


Amb*_*mar 5

Last but not the least....

Try Method One:

Simple Add these lines of code in the gradle file

dexOptions {
        incremental true
        javaMaxHeapSize "4g"
     }

Example:

android {
    compileSdkVersion XX
    buildToolsVersion "28.X.X"

    defaultConfig {
        applicationId "com.example.xxxxx"
        minSdkVersion 14
        targetSdkVersion 19
    }

dexOptions {
        incremental true
        javaMaxHeapSize "4g"
     }
}

*******************************************************************

Method Two:

Add these two lines of code in manifest file...

android:hardwareAccelerated="false" 
android:largeHeap="true"

Example:

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:hardwareAccelerated="false"
        android:largeHeap="true"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

It will Work for sure any of these cases.....
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

349484 次

最近记录:

6 年,4 月 前