Java – memory exception analysis hprof file dump
This is related to this problem
java. lang.OutOfMemoryError at android. graphics. BitmapFactory. nativeDecodeAsset(Native Method)
I created a dump file with a problem It provides the 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 what can we do now? How do I clear the problem?
My list_ Objects [context] - inbound file
CLASS NAME SHALLOW HEAP RETAINED HEAP byte[11059200] @ 0xb4979590 | 1,216 | 1,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
Please help me despair. 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(); } }
Solution
The idea is to shrink your image so that it looks good on a smaller screen, and you don't have to load the entire bitmap in memory
1) First, get the size of the ImageView / screen you want to display
2) By passing bitmapfactory Options. Injustdecodebounds to read the size of the bitmap This will give you the size of the bitmap instead of loading the entire bitmap
3) Gets the sample size Calculate the ratio of screen height and width to image height and width Use the smallest one to make the largest size look good
4) Finally, use the following functions to get down - sampled images that won't eat 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; }