Android:java.lang.OutOfMemoryError:未能分配一个23970828字节分配,其中包含2097152个空闲字节和2MB,直到OOM
我想显示已存储的SD卡的ImageView中的位图图像。 运行后,我的应用程序崩溃,并得到OutOfMemoryError的错误:
(java.lang.OutOfMemoryError:未能分配一个23970828字节分配,2097152空闲字节和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);
日志猫信息:
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)
OutOfMemoryError是在android中最常见的问题,尤其是处理位图。 由于缺less内存空间而无法分配对象,并且垃圾回收器无法释放一些空间时,由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">
你应该明确地阅读一些Android开发者的概念,特别是在这里: 高效地显示位图
阅读全部5个主题并重新编写代码。 如果它仍然不起作用,我们将很高兴看到你在教程材料中做了什么错误。
在这里SOF的这些types的错误的一些可能的答案
Android:BitmapFactory.decodeStream()内存不足,带有2MB空闲堆的400KB文件
如何解决Android中的java.lang.OutOfMemoryError问题
Android:java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
OutOfMemoryError解决scheme:位图大小超过虚拟机预算
编辑:从@cjnash的评论
对于任何在添加这行后仍然崩溃的人,请尝试将图片粘贴到res / drawable-xhdpi /文件夹中,而不是res / drawable /,这可能会解决您的问题。
你有没有试过在应用程序中添加这个清单? 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" >
其实你可以在你的清单中添加这些行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">
对我来说,问题是我的.png文件被解压缩成内存中真正巨大的位图,因为图像的尺寸非常大(即使文件大小很小)。
所以修复是简单地调整图像:)
在安装到ImageView之前调整图像大小 ,如下所示:
Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);
其中大小是ImageView的实际大小。 您可以通过测量来达到尺寸:
imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
并使用下一个尺寸的imageView.getMeasuredWidth()
和imageView.getMeasuredHeight()
进行scaling
。
使用Glide库和覆盖大小减小尺寸;
Glide.with(mContext).load(imgID).asBitmap().override(1080, 600).into(mImageView);
这应该工作
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; mBitmapInsurance = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
我得到了以下错误
“E / art:抛出OutOfMemoryError”无法分配一个47251468字节分配,16777120空闲字节和23MB,直到OOM“
在AndroidManifest.xml中添加android:largeHeap="true"
后,我摆脱了所有的错误
<application android:allowBackup="true" android:icon="@mipmap/guruji" android:label="@string/app_name" android:supportsRtl="true" android:largeHeap="true" android:theme="@style/AppTheme">
我已经通过调整图像大小来解决这个问题。 我正在使用xamarin表单。 减小PNG图像的大小解决了这个问题。
我也有这个问题。
与上面大多数人一样。 问题是由巨大的形象造成的。
只是调整一些图像,而不需要改变任何代码。
Soluton在您的清单文件中尝试使用并使用Glide Library
编译'com.github.bumptech.glide:glide:3.7.0'
**Use Glide Library and Override size to less size;** if (!TextUtils.isEmpty(message.getPicture())) { Glide.with(mContext).load(message.getPicture()) .thumbnail(0.5f) .crossFade() .transform(new CircleTransform(mContext)) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(holder.imgProfile); }
机器人:硬件加速=“假”
机器人:largeHeap = “真”
<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">
使用这个库
compile 'com.github.bumptech.glide:glide:3.7.0'
其工作快乐编码
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Paint; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; public class CircleTransform extends BitmapTransformation { public CircleTransform(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return circleCrop(pool, toTransform); } private static Bitmap circleCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; // TODO this could be acquired from the pool too Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(); paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return result; } @Override public String getId() { return getClass().getName(); } }
Bitmap image =((BitmapDrawable)imageView1.getDrawable()).getBitmap(); ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG,50/100,byteArrayOutputStream);
50/100如果使用100则原始分辨率可以停止应用程序内存不足。
如果50或小于100,这将是50%或小于100的分辨率,这样可以防止内存不足的问题
如果上传图像,请尝试降低图像质量,这是位图的第二个参数。 这是我的情况的解决scheme。 以前是90,然后我尝试了60(现在是在下面的代码中)。
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream); ByteArrayOutputStream baos = new ByteArrayOutputStream(); finalBitmap.compress(Bitmap.CompressFormat.JPEG,60,baos); byte[] b = baos.toByteArray();
我是Android开发新手,但我希望我的解决scheme可以帮助,它完美的工作在我的条件。 我使用Imageview,并将其背景设置为“src”,因为我试图做一个框架animation。 我得到了同样的错误,但是当我试图编码这个工作
int ImageID = this.Resources.GetIdentifier(questionPlay[index].Image.ToLower(), "anim", PackageName); imgView.SetImageResource(ImageID); AnimationDrawable animation = (AnimationDrawable)imgView.Drawable; animation.Start(); animation.Dispose();
尝试最简单的一个。 也许你的应用程序崩溃,因为你的图像大小(以MB为单位)太大,所以它没有为此分配空间。 所以在粘贴图像之前,只能通过任何查看器软件来缩小图像大小,或者在运行时从库中获取图像,而不是保存图像时压缩位图。 它为我工作。 绝对会为你。
在某些情况下(例如循环中的操作), 垃圾收集器比您的代码慢 。 您可以使用此答案中的帮助器方法来等待垃圾回收器 。
我遇到这个问题的时候,我并没有把我的旧活动转移到新的活动上。 我修好了finish();
Intent goToMain = new Intent(this,MainActivity.class); startActivity(goToMain); finish();
这对我有用:只需将图像从drawable文件夹移动到drawable-hdpi即可。
问题:未能分配一个37748748字节分配16777120空闲字节和17MB,直到OOM
解决scheme:1.打开你的清单文件2.在应用程序标签内只需添加下面两行
android:hardwareAccelerated="false" android:largeHeap="true"
例如:
<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">
我发现“drawable”文件夹中的图像将被转换为高清手机上的更大图像。 例如,一个200k的图像将被重新采样到更高的分辨率,如800k或32000k。 我不得不自己发现这个,迄今为止还没有看到这个堆内存陷阱的文档。 为了防止这种情况,我把所有的东西放在一个drawable-nodpi文件夹中(除了使用基于特定设备堆的BitmapFactory中的“选项”)。 我不能让我的应用程序的大小膨胀与多个可绘制的文件夹,特别是现在的屏幕清晰度范围是如此巨大。 棘手的是,studio现在并没有在项目视图中特别指定'drawable-nodpi'文件夹,它只是显示一个'drawable'文件夹。 如果你不小心,当你把一个图像拖放到studio中的这个文件夹时,它实际上不会被拖放到drawable-nodpi中:
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.
一定要点击对话框中的nodpi文件夹,因为项目视图不会像以前那样单独显示所有可绘制的文件夹,所以不会立即显示出错。 工作室早在很久之前就删除了它,在某些时候为我重新创build了“drawable”