{"id":1559,"date":"2022-08-30T15:17:32","date_gmt":"2022-08-30T15:17:32","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/27\/better-way-of-finding-out-where-resources-are-going-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:17:32","modified_gmt":"2022-08-30T15:17:32","slug":"better-way-of-finding-out-where-resources-are-going-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/better-way-of-finding-out-where-resources-are-going-collection-of-common-programming-errors\/","title":{"rendered":"Better way of finding out where resources are going?-Collection of common programming errors"},"content":{"rendered":"<p>I have a memory leak in my app. So naturally I want to fix it. The issue is either I don&#8217;t know how to use the DDMS and memory allocation tools or they are peices of crap (or both). So I&#8217;m wondering if there is another way I can figure out where all of my resources are being used or if someone can enlighten me on how to use the DDMS tools.<\/p>\n<p>PS: Yes, I know I have to click the debug button in the DDMS and then cause a HPROF dump and\/of use the Update heap button and do a GC. I can view the details of both but I can&#8217;t see any of the objects I have created. In short I can&#8217;t read what I&#8217;m viewing.<\/p>\n<p>Any help or enlightenment is greatly appreciated.<\/p>\n<p>~Aedon<\/p>\n<p>Edit 1:<\/p>\n<p>I added some logging throughout the drawing methods in my custom views. After some experimentation, I discoverd that the memory leak seams to be coming from this method.<\/p>\n<p>\/** Update the gauge independent static buffer cache for the background. *\/<\/p>\n<pre><code>private void regenerate() {\n    mNeedRegen = false;\n    \/\/ Prevent memory leaks by disposing of old bitmaps.\n    if (mBackground != null) { mBackground.recycle(); mBackground = null; }\n    \/\/ Our new drawing area\n    Log.d(TAG, getWidth() + \"\\t\" + getHeight());\n    mBackground = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);\n    Canvas backCanvas = new Canvas(mBackground);\n    float scale = (float)getWidth();\n    backCanvas.scale(scale, scale);\n    drawRim(backCanvas);\n    drawFace(backCanvas);\n    drawTitle(backCanvas);\n    if (!(this instanceof EmptySpace)) { drawGroupIcon(backCanvas); }\n    regenerateBackground(backCanvas);\n}\n<\/code><\/pre>\n<p>Now after some fiddling around in my app, I managed to cause this error:<\/p>\n<pre><code>     dalvikvm-heap  E  195364-byte external allocation too large for this process.\n  2935               dalvikvm  E  Out of memory: Heap Size=4871KB, Allocated=2636KB, Bitmap Size=19528KB\n  2935            GraphicsJNI  E  VM won't let us allocate 195364 bytes\n  2935         AndroidRuntime  D  Shutting down VM\n  2935               dalvikvm  W  threadid=1: thread exiting with uncaught exception (group=0x400259f8)\n  2935         AndroidRuntime  E  FATAL EXCEPTION: main\n  2935         AndroidRuntime  E  java.lang.OutOfMemoryError: bitmap size exceeds VM budget\n  2935         AndroidRuntime  E    at android.graphics.Bitmap.nativeCreate(Native Method)\n  2935         AndroidRuntime  E    at android.graphics.Bitmap.createBitmap(Bitmap.java:574)\n  2935         AndroidRuntime  E    at com.android.appion.arm.widgets.GaugeBase.regenerate(GaugeBase.java:239)\n  2935         AndroidRuntime  E    at com.android.appion.arm.widgets.GaugeBase.onSizeChanged(GaugeBase.java:86)\n  2935         AndroidRuntime  E    at android.view.View.setFrame(View.java:7101)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7028)\n  2935         AndroidRuntime  E    at android.widget.GridView.setupChild(GridView.java:1316)\n  2935         AndroidRuntime  E    at android.widget.GridView.makeAndAddView(GridView.java:1222)\n  2935         AndroidRuntime  E    at android.widget.GridView.makeRow(GridView.java:265)\n  2935         AndroidRuntime  E    at android.widget.GridView.fillSpecific(GridView.java:463)\n  2935         AndroidRuntime  E    at android.widget.GridView.layoutChildren(GridView.java:1122)\n  2935         AndroidRuntime  E    at android.widget.AbsListView.onLayout(AbsListView.java:1147)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)\n  2935         AndroidRuntime  E    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)\n  2935         AndroidRuntime  E    at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.widget.SlidingDrawer.onLayout(SlidingDrawer.java:331)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:909)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.widget.FrameLayout.onLayout(FrameLayout.java:333)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)\n  2935         AndroidRuntime  E    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)\n  2935         AndroidRuntime  E    at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.widget.FrameLayout.onLayout(FrameLayout.java:333)\n  2935         AndroidRuntime  E    at android.view.View.layout(View.java:7034)\n  2935         AndroidRuntime  E    at android.view.ViewRoot.performTraversals(ViewRoot.java:1049)\n  2935         AndroidRuntime  E    at android.view.ViewRoot.handleMessage(ViewRoot.java:1744)\n  2935         AndroidRuntime  E    at android.os.Handler.dispatchMessage(Handler.java:99)\n  2935         AndroidRuntime  E    at android.os.Looper.loop(Looper.java:144)\n  2935         AndroidRuntime  E    at android.app.ActivityThread.main(ActivityThread.java:4937)\n  2935         AndroidRuntime  E    at java.lang.reflect.Method.invokeNative(Native Method)\n  2935         AndroidRuntime  E    at java.lang.reflect.Method.invoke(Method.java:521)\n  2935         AndroidRuntime  E    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)\n  2935         AndroidRuntime  E    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)\n  2935         AndroidRuntime  E    at dalvik.system.NativeStart.main(Native Method)\n<\/code><\/pre>\n<p>The error itself makes sense. I ran out of memory. What doesn&#8217;t make sense is the bitmap I&#8217;m trying to make is 221px by 221px but aparently is 19528kb. If my math is right 221 * 221 = 48841 * 4 = 195364 <strong><em>bytes<\/em><\/strong> = 190.7kb. This doesn&#8217;t make any sense at all. Anywho, please take a look and see what you can find. BTW, the line in question from the error is the following (from the regenerate method)<\/p>\n<pre><code>mBackground = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);\n<\/code><\/pre>\n<ol>\n<li>\n<p>First, I think the Dalvik message is showing the wrong units whereas the GraphicsJNI error is correct:<\/p>\n<blockquote>\n<p>dalvikvm E Out of memory: Heap Size=4871KB, Allocated=2636KB, Bitmap Size=19528KB 2935<br \/>\nGraphicsJNI E VM won&#8217;t let us allocate 195364 bytes<\/p>\n<\/blockquote>\n<p>Keep in mind you can catch the memory error:<\/p>\n<pre><code>try{\n    mBackground = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);\n} catch(OutOfMemoryError e){\n    \/\/do something\n}\n<\/code><\/pre>\n<p>If your bitmaps are always the same size, I would recommend re-using them. If you are creating and destroying bitmaps fairly quickly, you run the risk of out-pacing the Garbage Collector and getting into this state.<\/p>\n<p>&#8211;Edit&#8211; As for your original question. I typically do the following when looking for a memory leak.<\/p>\n<p><strong>Initialization Steps<\/strong><\/p>\n<ol>\n<li>Make sure your app is set to be debuggable in the manifest<\/li>\n<li>Launch your app, open DDMS and select your application.<\/li>\n<li>Select the Allocation Tracker view and Start Tracking<\/li>\n<\/ol>\n<p><strong>Analysis<\/strong><\/p>\n<ol>\n<li>Let your app run, or perform some specific activities in your app that are causing memory issues.<\/li>\n<li>Click &#8220;Get Allocations&#8221; to update the tracker. You can now stop tracking if you like.<\/li>\n<li>In the filter, type your application name to narrow down the results.<\/li>\n<\/ol>\n<p>You need to think about what you are seeing here and whether it makes sense for your application. Should there be 1000&#8217;s of small memory allocations? Most likely not. At this point you can click on an allocation and see exactly which method and line number is causing the allocation.<\/p>\n<p>Another route to take is to enable heap updates for your app and use the heap explorer to track allocations. The heap explorer does not tell you <em>where<\/em> the allocation is coming from, but what it will tell you is that for instance:<\/p>\n<blockquote>\n<p>The number of 1k allocations is growing and never shrinking.<\/p>\n<\/blockquote>\n<p>You can then go into the Allocation Tracker and sort allocations by size to see where you are performing 1k allocations.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-11-27 11:51:33. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>I have a memory leak in my app. So naturally I want to fix it. The issue is either I don&#8217;t know how to use the DDMS and memory allocation tools or they are peices of crap (or both). So I&#8217;m wondering if there is another way I can figure out where all of my [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1559","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1559","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=1559"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1559\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=1559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=1559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=1559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}