Android 面试题 应用对内存是如何限制 八

🔥 OutOfMemeryError的原因 🔥

Android 针对每个应用有内存限制 , 当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)。
为什么会没有内存了呢?原因不外乎有两点:

1)分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。

2)应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。
**内存泄露:**申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了,因为申请者不用了,而又不能被虚拟机分配给别人用。
**内存溢出:**申请的内存超出了JVM能提供的内存大小,此时称之为溢出。

在之前没有垃圾自动回收的日子里,比如C语言和C++语言,我们必须亲自负责内存的申请与释放操作,如果申请了内存,用完后又忘记了释放,比如C++中的new了但是没有delete,那么就可能造成内存泄露。偶尔的内存泄露可能不会造成问题,而大量的内存泄露可能会导致内存溢出。
而在Java语言中,由于存在了垃圾自动回收机制,所以,我们一般不用去主动释放不用的对象所占的内存,也就是理论上来说,是不会存在"内存泄露"的。但是,如果编码不当,比如,将某个对象的引用放到了全局的Map中,虽然方法结束了,但是由于垃圾回收器会根据对象的引用情况来回收内存,导致该对象不能被及时的回收。如果该种情况出现次数多了,就会导致内存溢出,比如系统中经常使用的缓存机制。Java中的内存泄露,不同于C++中的忘了delete,往往是逻辑上的原因泄露。

🔥 为什么每个应用都限制最大内存使用 🔥

可以多任务同时运行,不可能每个任务都占用尽可能多的内存
如果堆很大,垃圾回收需要太多的时间缓存的清理需要先暂停所有应用,然后进行清理、整理。大概3、4、5毫秒

🔥 获取Android手机应用内存大小 🔥

手机不同其性能也不同,手机本身内存可能有大有小,所以针对每个应用的内存大小也不相同。
方法一

Dart 复制代码
方法一

adb shell
shell@sp9820w_6c10_rec:/ $ getprop |grep dalvik.vm.heapgrowthlimit
[dalvik.vm.heapgrowthlimit]: [48m]

方法二

Dart 复制代码
方法二

ActivityManager activityManager =(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.getMemoryClass();
activityManager.getLargeMemoryClass();

方法三

Dart 复制代码
adb shell cat /system/build.prop
dalvik.vm.heapstartsize=8m 
dalvik.vm.heapgrowthlimit=64m 
dalvik.vm.heapsize=256m

方法四:

Dart 复制代码
Runtime.getRuntime().maxMemory()

🔥 不同的参数详解 🔥

-dalvik.vm.heapstartsize

堆分配的初始大小,调整这个值会影响到应用的流畅性和整体ram消耗。这个值越小,系统ram消耗越慢,但是由于初始值较小,一些较大的应用需要扩张这个堆,从而引发gc和堆调整的策略,会应用反应更慢。相反,这个值越大系统ram消耗越快,但是程序更流畅。
-dalvik.vm.heapgrowthlimit

受控情况下的极限堆(仅仅针对dalvik堆,不包括native堆)大小,dvm heap是可增长的,但是正常情况下dvm heap的大小是不会超过dalvik.vm.heapgrowthlimit的值(非正常情况下面会详细说明)。这个值控制那些受控应用的极限堆大小,如果受控的应用dvm heap size超过该值,则将引发oom(out of memory)。
-dalvik.vm.heapsize

不受控情况下的极限堆大小,这个就是堆的最大值。不管它是不是受控的。这个值会影响非受控应用的dalvik heap size。一旦dalvik heap size超过这个值,直接引发oom。

🔥 应用app内存限制 🔥

Android app运行在vm上,而Android系统对vm heapsize做了一个硬性逻辑限制,就算物理内存富余,如果应用超出APP逻辑内存,APP就会出现内存溢出crash。

由程序控制操作的内存空间在heap上,分 java heapsize native heapsize ,Java申请的内存在vm heap上,所以如果java申请的内存大小超过VM的逻辑内存限制,就会出现内存溢出的异常。native层内存申请不受其限制, native层受native process对内存大小的限制。

🔥 查看Android设备上的对APP的内存限制 🔥

主要查看系统配置文件 build.prop,我们可以通过adb shell在 命令行窗口查看
查看设备app内存限制
adb shell getprop | findstr dalvik.vm.heapgrowthlimit
Android app 可以在AndroidManifast.xml里的<application android:largeHeap="true"/>标签里加入largeHeap开启内存加强,开启内存加强后,可使用内存会变大,这也是一个固定值,可以查看
adb shell getprop | findstr dalvik.vm.heapsize
可以查看更详细的
adb shell cat /system/build.prop | findstr dalvik.vm

相关推荐
ansondroider10 分钟前
Android adb 安装应用失败(安装次数限制)
android·adb·install
艾小逗2 小时前
uniapp中检查版本,提示升级app,安卓下载apk,ios跳转应用商店
android·ios·uni-app·app升级
tangweiguo030519874 小时前
Android Kotlin ViewModel 错误处理:最佳 Toast 提示方案详解
android·kotlin
火柴就是我4 小时前
android 基于 PhotoEditor 这个库 开发类似于dlabel的功能_2
android
每次的天空5 小时前
Android学习总结之Java篇(一)
android·java·学习
8931519606 小时前
Android开发Glide做毛玻璃效果
android·glide·android开发·android教程·glide做毛玻璃效果
whysqwhw6 小时前
DRouter代码走读
android
人生游戏牛马NPC1号7 小时前
学习Android(五)玩安卓项目实战
android·kotlin
前行的小黑炭9 小时前
Android Lifecycle代码分析:为什么使用;注解的方式为什么过期?源码分析;状态与事件
android
和煦的春风9 小时前
案例分析 | SurfaceFlinger 大片Runnable引起的卡顿
android·linux