如何以编程方式检测Android应用程序可用的应用程序堆大小?
我听说有一个功能可以在SDK的更高版本中执行此操作.无论如何,我正在寻找适合1.5及以上的解决方案.
我对这个关于Android操作系统的内存管理的问题很好奇,所以我希望对这个主题有一个非常详细的答案.
我想知道的是:
最重要的是:
到目前为止我所听到的(直到2013年):
是什么让我很好奇:
这两个限制都非常低.
我刚刚下载了Android任务管理器来检查我的设备RAM.我注意到有些应用程序使用大约40-50兆字节的RAM,这比上面提到的最大RAM使用量(比如说32 MB)要多得多.那么Android如何确定应用程序可以使用多少RAM?应用程序如何超出此限制?
此外,我注意到当使用大约30-40兆字节时,我的一些应用程序崩溃(被系统杀死?)和OutOfMemoryException.另一方面,我的手机上运行的应用程序使用100 MB以上的一段时间后(可能由于内存泄漏)不会崩溃或被杀死.因此,在确定可以节省多少RAM时,显然还取决于应用程序本身.这怎么可能?(我用带有768 MB RAM的HTC One S进行了测试)
免责声明:我不以任何方式与Android任务管理器应用程序相关联.
memory android memory-management out-of-memory android-memory
尽管我在drawable文件夹中有一个非常小的图像,我从用户那里得到了这个错误.我没有在代码中使用任何位图功能.至少故意:)
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:683)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:513)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:889)
at android.content.res.Resources.loadDrawable(Resources.java:3436)
at android.content.res.Resources.getDrawable(Resources.java:1909)
at android.view.View.setBackgroundResource(View.java:16251)
at com.autkusoytas.bilbakalim.SoruEkrani.cevapSecimi(SoruEkrani.java:666)
at com.autkusoytas.bilbakalim.SoruEkrani$9$1.run(SoruEkrani.java:862)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5602)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
根据这个stackTrace,我在这一行得到了这个错误('tv'是一个textView):
tv.setBackgroundResource(R.drawable.yanlis);
Run Code Online (Sandbox Code Playgroud)
问题是什么?如果您需要有关代码的其他信息,我可以添加它.谢谢!
我有一个OutOfMemory异常,画廊超过600x800像素JPEG.
环境
我一直在使用带有大约600x800像素的JPG图像的Gallery.
由于我的内容可能比图像更复杂,我将每个视图设置为一个RelativeLayout,它将JPView包装在ImageView中.
为了"加速"用户体验,我有一个4个插槽的简单缓存,预取(在一个looper中)左边有1个图像,1个图像右边显示图像并将它们保存在4槽HashMap中.
该平台
我使用的是256 RAM和128堆大小的AVD,屏幕为600x800.它也发生在Entourage Edge目标上,除了使用设备它更难调试.
问题
我一直在例外:
OutofMemoryError: bitmap size exceeds VM budget
Run Code Online (Sandbox Code Playgroud)
并且它在获取第五个图像时发生.我试图改变我的图像缓存的大小,它仍然是相同的.
奇怪的是:应该没有内存问题
为了确保堆限制远离我的需要,我在开始时定义了一个虚拟的8MB数组,并将其保留为未引用,以便立即调度.它是活动线程的成员,定义如下
static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }
Run Code Online (Sandbox Code Playgroud)
结果是堆大小接近11MB并且它们都是免费的. 注意我在它开始崩溃后添加了这个技巧.它使OutOfMemory不那么频繁.
现在,我正在使用DDMS.在崩溃之前(崩溃后变化不大),DDMS显示:
ID Heap Size Allocated Free %Used #Objects
1 11.195 MB 2.428 MB 8.767 MB 21.69% 47,156
Run Code Online (Sandbox Code Playgroud)
并在详细信息表中显示:
Type Count Total Size Smallest Largest Median Average
free 1,536 8.739MB 16B 7.750MB 24B 5.825KB
Run Code Online (Sandbox Code Playgroud)
最大的块是7.7MB.然而LogCat说:
ERROR/dalvikvm-heap(1923): 925200-byte external allocation too large for this process.
Run Code Online (Sandbox Code Playgroud)
如果你介意中位数和平均值之间的关系,可以假设大多数可用的块非常小.但是,有一个块足够大的位图,它是7.7M.怎么还不够呢?
注意:我记录了一个堆跟踪.在查看分配的数据量时,感觉不会超过2M.它确实与DDMS的可用内存报告相匹配. …
我想通过两种方式知道我的android应用程序使用的堆空间量: - 以编程方式 - 通过DDMS.
在发布之前我已经提到了这篇文章.在Debug.getNativeHeapSize()那篇文章中,提到了,返回堆大小.这是我应该使用的确切方法,以编程方式检测堆大小?如果是这样,我应该在哪里记录它以获得我的应用程序的正确堆大小使用?
我正在使用OSMdroid库开发一个离线mapView.我的tilesource加载了tile,但渲染稳定.但事实是在我的日志消息中,我不断收到此错误:
GC_FOR_ALLOC freed 6346K, 7% free , paused 143ms, total 143ms
我不确定如何调试这个?任何想法,我有任何内存泄漏?
我可以获得总可用内存:
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
memoryInfo.availMem;
Run Code Online (Sandbox Code Playgroud)
但是,如何获得设备的总内存(RAM)?
我读过: 如何在Android中发现我的应用程序的内存使用情况?
它似乎没有添加pidMemoryInfo.getTotalPss()给我总内存.
我在android平台上开发了一个文件解析应用程序.如何检查应用程序实际耗尽的内存量?我尝试了adb shell cat/proc/meminfo命令,但这并没有给我我的应用程序使用了多少内存.它只是提供有关整体内存的一般信息.应用程序通常会消耗多少内存?通常或不寻常的是什么?任何帮助表示赞赏.谢谢 !
我知道在Android平台上有Dalvik(JVM)堆和Native堆.Dalvik GC在本机堆上没有工作.但我不确定这是如何工作的,我的意思是Android操作系统是如何将它们分开的?
可能的情况1:由独立的内存硬件组成(我不相信太多)
可能的情况2:Android操作系统对两个堆都有固定的内存量
可能的情况3:Android OS必须在必要时将部分Dalvik内存堆分配为本机堆,因此本机堆和Dalvik堆的大小是灵活的.
哪一个是真的,或者我没有提到的可能性?
我正在为Android Honeycomb编写一个内存密集型应用程序,并且尽可能地对recycle()未使用的Bitmaps 进行了非常小心的处理.实际上,这对于应用程序来说是必要的,因为Bitmaps不断地循环进出内存.但是,我刚刚实现onConfigurationChanged()了Activity,因此(由于多种原因)我试图将内存释放例程放入其中onStop().
目前我的onStop()方法:
Views来显示默认值Drawable;recycle()对Bitmap以前使用的这些小号View秒;Bitmaps的引用.不幸的是,使用Eclipse内存分析器,它似乎对内存使用没有任何影响.
你可以想象,我已经做了很多努力,用一种名义上垃圾收集的语言来释放资源,我希望能有更多的效果.所以我的问题是:做recycle()什么?它是否实际上触发了垃圾收集,或者系统是否会保留在内存中 - 即使你调用System.gc()-until它感觉需要摆脱某些东西?
NB我知道Bitmaps实际上并没有被保存在常规堆中,但我认为调用recycle()足以确保它们被从本机堆中删除.
答案的一部分
我发现如果一个ImageView包含Bitmap已经被回收的Bitmap数据,那么数据仍会保留在内存中,直到setImageBitmap(null)被调用ImageView.甚至可能是这种情况,如果setImageResource(...)或被setImageDrawable(...)调用(它们是在一个相对较小的九个补丁中加载 - 但是,MAT分析显示这并没有删除Bitmap包含在私有成员中的大数据ImageView).简单地调用此函数onStop()已经从我们的应用程序堆中剔除了大约10MB.显然,这可能不适用于预装的Honeycomb版本的Android.
android ×10
memory ×5
bitmap ×2
android-ndk ×1
api ×1
dalvik ×1
ddms ×1
gallery ×1
heap ×1
heap-memory ×1
imageview ×1
java ×1
performance ×1
recycle ×1