请注意我没有内存泄漏.我的问题是一个更微妙的问题.
我最近写了一个Android应用程序,它进行图像处理.图像作为位图加载,然后以像素复制,以使用大量内存的方式处理(考虑浮点表示和填充中的傅里叶变换),然后转换回位图并保存.
问题是,至少通过android OS 2.3,总内存限制(通常为16MB)是组合java和(外部存储)位图,并且即使在内存中,java高水位标记也不会下降(我可以辨别)是免费的(成功GC'd),这意味着当我去分配最终的位图时,我经常"内存不足",即使到那时我已经释放了(和GC'd)大部分空间.即,我从来不需要一次完整的16MB,但是Bitmaps留下的空间似乎是16MB减去MAX历史java堆的使用量(与当前使用情况相反).
我看了一个Android开发人员关于内存问题的技术演讲,他暗示这个问题已经在操作系统的后续版本中得到修复(他们将Bitmap内存移动到java堆空间中),但与此同时大多数人都希望使用我的应用正在运行2.2或2.3.
长话短说,我想知道java堆是否曾被压缩(实际上是去碎片),以便高水位标记缩小(如果是这样,如何实现它)?
如果没有,那么有人有另一个建议如何处理这个问题?
我从图库中获取照片并在ImageView中显示.但我的问题是有时工作正常,有时候会出错.错误是位图大小超过VM预算..
记录错误..
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at androidexperts.wp7.facebook.WP7FB.sharePhotoDialog(WP7FB.java:200)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at androidexperts.wp7.facebook.WP7FB.onActivityResult(WP7FB.java:269)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.app.Activity.dispatchActivityResult(Activity.java:3890)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.app.ActivityThread.deliverResults(ActivityThread.java:3511)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3557)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.app.ActivityThread.access$2800(ActivityThread.java:125)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2063)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.os.Handler.dispatchMessage(Handler.java:99)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.os.Looper.loop(Looper.java:123)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at android.app.ActivityThread.main(ActivityThread.java:4627)
04-01 10:14:57.098: ERROR/AndroidRuntime(12863): at java.lang.reflect.Method.invokeNative(Native Method)
04-01 10:14:57.098: …Run Code Online (Sandbox Code Playgroud) 我认为我的ImageView存在问题.我创建了一个画廊,在那里我可以触摸图像并将其放在我的ImageView下面:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/fonddegrade">
<Gallery android:layout_height="wrap_content"
android:id="@+id/gallery"
android:layout_width="fill_parent" />
<ImageView android:layout_below="@+id/gallery"
android:layout_height="wrap_content"
android:id="@+id/laphoto"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"/>
Run Code Online (Sandbox Code Playgroud)
这完全适用于小图像,但不适用于大图像(3264*1952).当我触摸它(所以,试图把它放在ImageView中),我有一个错误,我的应用程序崩溃.这是我显示图像的java代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.photo);
File images; // Trouver le bon endroit de stockage
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
images = new File("/sdcard/MyPerformance/Photo");
else
images = this.getFilesDir();
images.mkdirs();
File[] imagelist = images.listFiles(new FilenameFilter(){
@Override
public boolean accept(File dir, String name)
{
return ((name.endsWith(".jpg"))||(name.endsWith(".png")));
}
});
mFiles = new String[imagelist.length];
for(int i = 0 ; i< imagelist.length; i++)
{
mFiles[i] = imagelist[i].getAbsolutePath();
} …Run Code Online (Sandbox Code Playgroud) 我正在制作可以合成相机预览和png的相机应用程序.
我想将图像保存在onPictureTaken回调中
我的来源如下
public void onPictureTaken(byte[] data, Camera camera) {
//preview from camera
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
// overlay image
Bitmap overlayBmp = overlay.getDrawingCache();
//blank beatmap
Bitmap blankBitmap =
Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
//make canvas
Canvas canvas = new Canvas(blankBitmap);
//composite image
canvas.drawBitmap(bitmap, null,new Rect(0, 0, bitmap.getWidth(),
bitmap.getHeight()), null);
canvas.drawBitmap(overlayBmp, null,new Rect(0, 0, bitmap.getWidth(),
bitmap.getHeight()), null);
Run Code Online (Sandbox Code Playgroud)
然而,它显示了outofmemoryerrorror,我怎么能解决这个问题..?
05-20 15:13:49.114: E/AndroidRuntime(31647): FATAL EXCEPTION: main
05-20 15:13:49.114: E/AndroidRuntime(31647): java.lang.OutOfMemoryError
05-20 15:13:49.114: E/AndroidRuntime(31647): at android.graphics.Bitmap.nativeCreate(Native Method)
05-20 15:13:49.114: E/AndroidRuntime(31647): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
05-20 15:13:49.114: …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个库或一些想法,我可以如何将磁盘上的部件或磁带直接加载到磁盘,然后再将部分加载到磁盘.所以我认为可以做到的两种方式是将整个图像加载到磁盘上,直接使用ram从url读取和写入缓冲区,然后当磁盘上的图像时,如何创建只有部分的位图对于图像,这样我就不会加载它并将它们放入ListView.
问题是我处理的是非常长的图像(10K +像素长,宽度为4-600),如果在一个位图中加载,它们会占用大量的ram.我不能像谷歌android教程在处理大型位图部分那样缩小它们,因为这会导致宽度太小而无法处理.因此,如果我能以某种方式在磁盘上生成小位图条,我可以通过加载它们来ListView防止将图像作为一个整体加载到ram中.
现在我正在将长图像从位图中分解成条子,我意识到这并没有真正完成我想要做的事情,因为整个图像被加载到内存中的位图然后被分解,然后GC(所以无论如何,我正在使用ram的完全卸载.我正在测试一个新的顶级Android手机和应用程序工作正常,但堆大小达到80mb +与较大的图像暂时在RAM中,因为它打破了位图,这将是具有较低堆限制的设备的问题
我知道有关内存不足的问题,但我找不到任何解决方案
在Bitmap Factory中我得到了内存异常,甚至使用
inSampleSize=1
Run Code Online (Sandbox Code Playgroud)
所以我习惯用try catch out of memory of exception来包围它,因为这是一个不好的做法
try{
.........
......
}catch (OutOfMemoryError e)
{}
Run Code Online (Sandbox Code Playgroud)
内存不足异常也被捕获但我的问题是我们抓住了这个异常之后
清除或重新分配GC的堆内存
有什么办法吗?
我用
的System.gc();
没有用请帮忙!!!!!!!
Run Code Online (Sandbox Code Playgroud)not even Bitmap also for GridView Orientation i found this exception Clamp target GC heap from 17.333MB to 16.000MB Out of memory on a 140416-byte allocation.
这是我的viewpager数组中的drawable,当我运行它时,我会导致内存不足错误,有没有办法减少图像大小等?我做了很多搜索,但我也不能使用它们..请帮助...
GalImages = new int[] { R.drawable.tutorials_01_android_en,R.drawable.tutorials_02_android_en,R.drawable.tutorials_03_android_en,R.drawable.tutorials_04};break
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
final int temp = position;
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setImageResource(GalImages[position]);
((ViewPager) container).addView(imageView, 0);
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {}
});
return imageView;
}
Run Code Online (Sandbox Code Playgroud) 我有一个非常小的活动,必须显示一个图像.
如果图像不是很小(例如1.12 Mb 2560x1920),则在更改屏幕方向上会产生内存不足.我试过getDrawable.setCallback(null)但没有运气.
我哪里错了?
public class Fullscreen extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.gc();
setContentView(R.layout.fullscreen);
ImageView imageView = (ImageView) findViewById(R.id.full_screen_image);
long imageId = 2;
imageView.setImageURI(Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + imageId));
}
}
Run Code Online (Sandbox Code Playgroud) 所以我有一个懒惰的图像加载器ListView.我还使用本教程来更好地管理内存并将SoftReferenceBitmap图像存储在我的ArrayList.
我的ListView作品从数据库中加载了8张图像,然后一旦用户滚动到底部,它就会加载另外8张等等.当有大约35张图像或更少时,没有问题,但是还有我的应用程序强制关闭OutOfMemoryError.
我无法理解的是我在try catch中有我的代码:
try
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(image, 0, image.length, o);
//Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while(true)
{
if(width_tmp/2 < imageWidth || height_tmp/2 < imageHeight)
{
break;
}
width_tmp/=2;
height_tmp/=2;
scale++;
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale; …Run Code Online (Sandbox Code Playgroud) 这是我的代码:
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap foto = BitmapFactory.decodeByteArray(data, 0, data.length);
wid = foto.getWidth();
hgt = foto.getHeight();
Bitmap newImage = Bitmap.createBitmap(wid, hgt, Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(foto, 0f, 0f, null);
if (newImage.getWidth() > newImage.getHeight()) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
newImage.createBitmap(newImage, 0, 0, wid, hgt, matrix, true);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的错误:
FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:689)
at android.graphics.Bitmap.createBitmap(Bitmap.java:666)
at android.graphics.Bitmap.createBitmap(Bitmap.java:633)
at com.supratecnologia.activity.Camera_Activity.onPictureTaken(Camera_Activity.java:189)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:768)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at …Run Code Online (Sandbox Code Playgroud)