同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现不足时,Android会尝试停止一些进程从而释放足够的资源给其他新的进程使用, 也能保证用户正在访问的当前进程有足够的资源去及时地响应用户的事件。Android会根据进程中运行的组件类别以及组件的状态来判断该进程的重要性,Android会首先停止那些不重要的进程。按照重要性从高到低一共有五个级别就是我们常说的:前台进程、可见进程、服务进程、后台进程、空进程(此处概念略,大家自己查) 还有个小扩展:当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。Android的UI是单线程(Single-threaded)的。为了避免拖住GUI,一些较费时的对象应该交给独立的线程去执行。如果幕后的线程来执行UI对象,Android就会发出错误讯息?CalledFromWrongThreadException。以后遇到这样的异常抛出时就要知道怎么回事咯!**
**? ? ? ? ? ? 好了,铺垫知识就写这么多了,下面直接进入主题了:OOM调试**
方式一:使用内存监测工具 DDMS –> Heap:(真机、模拟器均可使用)
**? ? ? ? ? ? ? ?1. 启动eclipse后,切换到DDMS透视图,并确认Devices视图、Heap视图都是打开的,没打开的直接Window>ShowView>自己选;** **? ? ? ? ? ? ? ?2. 将手机通过USB链接至电脑,链接时需要确认手机是处于“USB调试”模式**
**? ? ? ? ? ? ? ?3. 链接成功后,在DDMS的Devices视图中将会显示手机设备的序列号,以及设备中正在运行的部分进程信息;**
**? ? ? ? ? ? ? ?4. 点击选中想要监测的进程,如果在进程列表中未出现你的进程的话随便选中一条让Device一排的工具处于可用状态,再点击下Update Heap让其自动找到我们跑的应用的进程,比如临时跑的两个应用进程如图
**?5. 点击Heap视图中的“Cause GC”按钮;**
**?6.点击Cause GC之后就可以看到我们应用的内存情况如下图:**
说明: a) 点击“Cause GC”按钮相当于向虚拟机请求了一次gc操作; b) 当内存使用信息第一次显示以后,无须再不断的点击“Cause GC”,Heap视图界面会定时刷新,在对应用的不断的操作过程中就可以看到内存使用的变化; c) 内存使用信息的各项参数根据名称即可知道其意思,不知道具体意思的朋友自行用工具(有道、词霸查去)
**? ? ? ?知道工具使用了,那么如何才能知道我们的程序是否有内存泄漏的可能性呢。这里需要注意一个值:Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,如果大家想要看“Total Size”是分配的具体信息可以点击“data object这一行来查看详细信息,如下图”(大家看不清楚的点击看大图)**
一般情况下,在data object行的“Total Size”这个值的大小决定了是否会有内存泄漏。可以这样判断: a) 不断的操作当前应用,同时注意观察data object的Total Size值; b) 正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对 象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平; c) 反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大, **? 直到到达一个上限后导致进程被杀掉。**
**? ? ? ? ? ? ?Android为应用进程分配的内存上限如下所示:(下面这些是网上查到的,不懂下面的语法,但知道有限制这么一回事就够了,此处不研究下面的代码)**
killed by the kernel. These are used in ActivityManagerService setprop ro.FOREGROUND_APP_ADJ 0 setprop ro.VISIBLE_APP_ADJ 1 setprop ro.SECONDARY_SERVER_ADJ 2 setprop ro.BACKUP_APP_ADJ 2 setprop
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
开源分享完整内容戳这里
ro.HOME_APP_ADJ 4 setprop ro.HIDDEN_APP_MIN_ADJ 7 setprop ro.CONTENT_PROVIDER_ADJ 14 setprop ro.EMPTY_APP_ADJ 15 Define the memory thresholds at which the above process classes will be killed. These numbers are in pages (4k) setprop ro.FOREGROUND_APP_MEM 1536 setprop ro.VISIBLE_APP_MEM 2048 setprop ro.SECONDARY_SERVER_MEM 4096 setprop ro.BACKUP_APP_MEM 4096 setprop ro.HOME_APP_MEM 4096 setprop ro.HIDDEN_APP_MEM 5120 setprop ro.CONTENT_PROVIDER_MEM 5632 setprop ro.EMPTY_APP_MEM 6144 Write value must be consistent with the above properties. Note that the driver only supports 6 slots, so we have HOME_APP at the same memory level as services. write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15 write /proc/sys/vm/overcommit_memory 1 write /proc/sys/vm/min_free_order_shift 4 write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144 Set init its forked children’s oom_adj write /proc/1/oom_adj -16
方式二:
**内存监测工具 DDMS –> Heap?** **使用内存分析工具 MAT(Memory Analyzer Tool)?** (一) 生成.hprof文件 (生成很简单,直接点击Device 工具栏中的 Dump HPROF file即可生成) **(二) 使用MAT导入.hprof文件?** (三) 使用MAT的视图工具分析内存
**? 总之,使用DDMS的Heap视图工具可以很方便的确认我们的程序是否存在内存泄漏的可能性。这个地方顺带着也简单的说一下,如果大家想要跟踪更详细的内存是怎样分配的话,可以学着使用下Windows>ShowView>Allocation Tracker工具来定位你的内存什么时候被什么东西占用了,是bundlea或HashMap或ArrayList焦点或是其它的什么占用了这些都可以在这个插件中查看到的,简单的使用方法就是:选中Device进程列表中的某一个进程,让Allocation Tracker里面的跟踪工具处于可用状态,点击Stop Tracking来跟踪程序,过一定时间后,点击Get Allocations来获取内存分配的消息就可以查看更为详细的内存分配情况了,如下图:**
**? ? ? ? ? Allocation Tracker这个小工具比较简单, 在这个地方不一一说明了,想学的朋友们自己点击看看就会知道里面的参数是什么意思了……_………**最后,还是一样,在内存管理方面还要学的东西很多,如果文章中有讲的不清楚或不足之处,大家留言批评并提出更好的建议,一定及时改进,在此先谢谢大家啦,吼吼学习学习!大家加油,一起进步!!!
想获取更多相关Android资料群653583088。本群提供免费的学习指导以及免费的解答不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导进群修改群备注:开发年限-地区-经验方便解答问题]
oid资料群653583088。本群提供免费的学习指导以及免费的解答不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导进群修改群备注:开发年限-地区-经验方便解答问题]
|