内存不够的异常+分析HPROF文件转储 [英] out of memory exception + analyzing hprof file dump

查看:1170
本文介绍了内存不够的异常+分析HPROF文件转储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是与这个问题有关

<一个href="http://stackoverflow.com/questions/24134270/java-lang-outofmemoryerror-at-android-graphics-bitmapfactory-nativede$c$cassetn">java.lang.OutOfMemoryError在android.graphics.BitmapFactory.nativeDe $ C $检测板(本机方法)

我创建了问题转储文件..它提供了以下信息

 的byte []被加载的一个实例&lt;系统类加载器&gt;中占地1,10,59,216
(51.02%)字节。所述存储器中累积的字节[]的一个实例
 通过加载;系统类加载器&GT;&LT。

关键词的byte []
 

所以现在可以做什么?我如何解决这一问题?

我list_objects [背景] -inbound文件

 类名浅层HEAP未分配利润HEAP
字节[11059200] @ 0xb4979590 | 1,10,59,216 | 1,10,59,216
mBuffer android.graphics.Bitmap @ 0xb3dc68d8 | 48 | 48
mBitmap android.graphics.drawable.BitmapDrawable @ 0xb3dbba60 | 72 | 144
mBackground android.widget.RelativeLayout @ 0xb3db3fc0 | 512 | 10144
mBitmap android.graphics.drawable.BitmapDrawable $ BitmapState @ 0xb3dc0068 | 40 | 40
mBitmapState android.graphics.drawable.BitmapDrawable @ 0xb3dbba60 | 72 | 144
指涉java.lang.ref.WeakReference @ 0xb3dc2d68 | 24 | 24
 

请帮助我绝望。我该如何解决内存问题?

我home_screen.java

 保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.home_page);
    主要();
 私人无效的main(){
    // TODO自动生成方法存根


    最终按钮回家;
    最终按钮公司简介;
    最终按钮的接触;
    最终按钮的客户;
    最终巴顿服务;

    尝试
    {

    家庭=(按钮)findViewById(R.id.btnHome);
    公司简介=(按钮)findViewById(R.id.btnAboutus);
    客户端=(按钮)findViewById(R.id.btnClients);
    联系人=(按钮)findViewById(R.id.btnContacts);
    服务=(按钮)findViewById(R.id.btnServices);

    home.setOnClickListener(新OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根
            位图B = BitmapFactory.de codeResource(getResources(),R.drawable.home1);
            绘制对象D =新BitmapDrawable(getResources(),B);
            home.setBackgroundDrawable(四);
            System.gc()的;
            意图myIntent =新的意图(Home_Screen.this,Button_Anime.class);
            startActivity(myIntent);
        }
    });
    aboutus.setOnClickListener(新OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根
            位图B = BitmapFactory.de codeResource(getResources(),R.drawable.about1);
            绘制对象D =新BitmapDrawable(getResources(),B);
            aboutus.setBackgroundDrawable(四);
            意图myIntent =新的意图(Home_Screen.this,AboutUs.class);
            startActivity(myIntent);
        }
    });
    clients.setOnClickListener(新OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根

            位图B = BitmapFactory.de codeResource(getResources(),R.drawable.clients1);
            绘制对象D =新BitmapDrawable(getResources(),B);
            clients.setBackgroundDrawable(四);
            意图myIntent =新的意图(Home_Screen.this,Clients.class);
            startActivity(myIntent);
        }
    });
    contacts.setOnClickListener(新OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根

            位图B = BitmapFactory.de codeResource(getResources(),R.drawable.contact1);
            绘制对象D =新BitmapDrawable(getResources(),B);
            contacts.setBackgroundDrawable(四);
            意图myIntent =新的意图(Home_Screen.this,Contacts.class);
            startActivity(myIntent);
        }
    });
    services.setOnClickListener(新OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根

            位图B = BitmapFactory.de codeResource(getResources(),R.drawable.services1);
            绘制对象D =新BitmapDrawable(getResources(),B);
            services.setBackgroundDrawable(四);
            意图myIntent =新的意图(Home_Screen.this,Services.class);
            startActivity(myIntent);
        }
    });

    }
    赶上(例外五)
    {
        e.printStackTrace();
    }
}
 

解决方案

这样做是为了降低采样的图像,它看起来很不错的小屏幕和你没有加载在内存中的整个位图。

1)首先获得您的ImageView /屏幕,您将展示上的大小。

2),阅读你的大小传入 BitmapFactory.Options.inJustDe codeBounds 位图。这会给你的位图的大小,而不是加载整个位图。

3)获取insample大小。计算的高度和宽度的屏幕的比例对图像的高度和宽度。用最小的一个,这样,最大的尺寸看起来不错。

4)最终使用下面的函数来获取下采样图像不会吃了你的记忆。

2)(code)

  BitmapFactory.Options bitmapOptions =新BitmapFactory.Options();
bitmapOptions.inJustDe codeBounds = TRUE;
BitmapFactory.de codeStream(的InputStream,空,bitmapOptions);
INT ImageWidth等= bitmapOptions.outWidth;
INT imageHeight = bitmapOptions.outHeight;
inputStream.close();
 

4)(code)

 私人位图downscaleBitmapUsingDensities(最终诠释的采样大小,最终诠释imageResId)
  {
  最后的选项bitmapOptions =新的选项();
  bitmapOptions.inDensity =采样大小;
  bitmapOptions.inTargetDensity = 1;
  最后的位图scaledBitmap = BitmapFactory.de codeResource(getResources(),imageResId,bitmapOptions);
  scaledBitmap.setDensity(Bitmap.DENSITY_NONE);
  返回scaledBitmap;
  }
 

this is in connection with this question

java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)

i created the dump file in question.. and it gives following information

One instance of "byte[]" loaded by "<system class loader>" occupies 1,10,59,216
(51.02%) bytes. The memory is accumulated in one instance of "byte[]" 
 loaded by "<system class loader>".

Keywords byte[]

so now what can be done?? how do i clear the problem??

my list_objects[context]-inbound file

CLASS NAME                                                                 SHALLOW HEAP   RETAINED HEAP  
byte[11059200] @ 0xb4979590                                               |  1,10,59,216 |   1,10,59,216
mBuffer android.graphics.Bitmap @ 0xb3dc68d8                              |48            | 48
mBitmap android.graphics.drawable.BitmapDrawable @ 0xb3dbba60             | 72           | 144
mBackground android.widget.RelativeLayout @ 0xb3db3fc0                    |512           | 10,144
mBitmap android.graphics.drawable.BitmapDrawable$BitmapState @ 0xb3dc0068 |40          | 40
mBitmapState android.graphics.drawable.BitmapDrawable @ 0xb3dbba60        |72          |  144
referent java.lang.ref.WeakReference @ 0xb3dc2d68                         |24          |  24

pls help i am desperate. how can i solve the memory problem??

my home_screen.java

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home_page);
    main();
 private void main() {
    // TODO Auto-generated method stub


    final Button home;
    final Button aboutus;
    final Button contacts;
    final Button clients;
    final Button services;

    try
    {

    home = (Button)findViewById(R.id.btnHome);
    aboutus = (Button)findViewById(R.id.btnAboutus);
    clients = (Button)findViewById(R.id.btnClients);
    contacts = (Button)findViewById(R.id.btnContacts);
    services = (Button)findViewById(R.id.btnServices);

    home.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.home1);
            Drawable d = new BitmapDrawable(getResources(),b);              
            home.setBackgroundDrawable(d);
            System.gc();
            Intent myIntent = new Intent(Home_Screen.this, Button_Anime.class);
            startActivity(myIntent);
        }
    });
    aboutus.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.about1 );
            Drawable d = new BitmapDrawable(getResources(),b); 
            aboutus.setBackgroundDrawable(d);
            Intent myIntent = new Intent(Home_Screen.this, AboutUs.class);
            startActivity(myIntent);
        }
    });
    clients.setOnClickListener(new  OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.clients1 );
            Drawable d = new BitmapDrawable(getResources(),b); 
            clients.setBackgroundDrawable(d);
            Intent myIntent = new Intent(Home_Screen.this, Clients.class);
            startActivity(myIntent);
        }
    });
    contacts.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.contact1);
            Drawable d = new BitmapDrawable(getResources(),b);
            contacts.setBackgroundDrawable(d);
            Intent myIntent = new Intent(Home_Screen.this, Contacts.class);
            startActivity(myIntent);
        }
    });
    services.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.services1 );
            Drawable d = new BitmapDrawable(getResources(),b);
            services.setBackgroundDrawable(d);
            Intent myIntent = new Intent(Home_Screen.this, Services.class);
            startActivity(myIntent);
        }
    });

    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

解决方案

The idea is to down sample your image so that it looks good on the smaller screen and that you dont have to load the entire bitmap in memory.

1) First get the size of your ImageView/ screen that you will be displaying on.

2) Read the size of you Bitmap by passing in BitmapFactory.Options.inJustDecodeBounds. This will give you the size of the Bitmap rather than loading the entire bitmap.

3) Get a insample size. Calculate the ratio of height and width of the screen to the image height and width. Use the smallest one so that the biggest dimension looks good.

4) Final use the function below to get the down sampled image that wont eat up your memory.

2)(code)

BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, bitmapOptions);
int imageWidth = bitmapOptions.outWidth;
int imageHeight = bitmapOptions.outHeight;
inputStream.close();

4)(code)

private Bitmap downscaleBitmapUsingDensities(final int sampleSize,final int imageResId)
  {
  final Options bitmapOptions=new Options();
  bitmapOptions.inDensity=sampleSize;
  bitmapOptions.inTargetDensity=1;
  final Bitmap scaledBitmap=BitmapFactory.decodeResource(getResources(),imageResId,bitmapOptions);
  scaledBitmap.setDensity(Bitmap.DENSITY_NONE);
  return scaledBitmap;
  }

这篇关于内存不够的异常+分析HPROF文件转储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆