Android中App可分配内存的大小

2024-06-10 07:32

本文主要是介绍Android中App可分配内存的大小,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

现在真实测试结果:  

1,为了搞清楚每个应用程序在Android系统中最多可分配多少内存空间,我们使用了真机进行测试,测试机型为魅族MX4 Pro,3G内存。

测试方法是直接申请一块较大的内存空间,看应用程序在最多申请多大的内存空间时会崩溃。

  结果:(1)未设定属性android:largeheap = "true"时,可以申请到的最大内存空间为221M。

     (2)设定属性android:largeheap = "true"时, 可以申请的最大内存空间为478M,是原来的两倍多一些。

  网上有网友提出可申请到的最大内存空间与手机配置有关,以后会加以验证。


2.实测,不准确, 准确的说话是 google原生OS的默认值是16M,但是各个厂家的OS会对这个值进行修改。

比如本人小米2S为例,这个值应该是96M。

 

Runtime rt=Runtime.getRuntime();
long maxMemory=rt.maxMemory();
log.i("maxMemory:",Long.toString(maxMemory/(1024*1024)));
這個可以直接得到app可使用的最大memory size算出來是MB, 获得的是heapgrowthlimit


先看机器的内存限制,在/system/build.prop文件中:
heapgrowthlimit就是一个普通应用的内存限制,用ActivityManager.getLargeMemoryClass()获得的值就是这个。
而heapsize是在manifest中设置了largeHeap=true 之后,可以使用的最大内存值
结论就是,设置largeHeap的确可以增加内存的申请量。但不是系统有多少内存就可以申请多少,而是由dalvik.vm.heapsize限制。
你可以在app manifest.xml加 largetHeap=true
可以申請較多的記憶體 ,但還是有機會爆掉.

<application
     .....
     android:label="XXXXXXXXXX"
     android:largeHeap="true">
    .......
</application>


cat /system/build.prop   //读取这些值
getprop dalvik.vm.heapsize  //如果build.prop里面没有heapsize这些值,可以用这个抓取默认值
setprop dalvik.vm.heapsize 256m  //设置

-----------------------    build.prop 部分内容 ---------------------

dalvik.vm.heapstartsize=8m
dalvik.vm.heapgrowthlimit=96m
dalvik.vm.heapsize=384m
dalvik.vm.heaputilization=0.25
dalvik.vm.heapidealfree=8388608
dalvik.vm.heapconcurrentstart=2097152
ro.setupwizard.mode=OPTIONAL
ro.com.google.gmsversion=4.1_r6
net.bt.name=Android
dalvik.vm.stack-trace-file=/data/anr/traces.txt



最早的说法:

1、APP默认分配内存大小

在Android里,程序内存被分为2部分:native和dalvik,dalvik就是我们普通的java使用内存,也就是我们上一篇文章分析堆栈的时候使用的内存。我们创建的对象是在这里面分配的,对于内存的限制是 native+dalvik 不能超过最大限制。android程序内存一般限制在16M,也有的是24M(早期的Android系统G1,就是只有16M)。具体看定制系统的设置,在Linux初始化代码里面Init.c,可以查到到默认的内存大小。有兴趣的朋友,可以分析一下虚拟机启动相关代码。这块比较深入,目前我也没时间去分析,后面有空会去钻研一下。

  gDvm.heapSizeStart = 2 * 1024 * 1024;   // heap初始化大小为2M
  gDvm.heapSizeMax = 16 * 1024 * 1024;    // 最大的heap为16M
  

  2、Android的GC如何回收内存

Android的一个应用程序的内存泄露对别的应用程序影响不大。为了能够使得Android应用程序安全且快速的运行,Android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的。Android为不同类型的进程分配了不同的内存使用上限,如果程序在运行过程中出现了内存泄漏的而造成应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉,这使得仅仅自己的进程被kill掉,而不会影响其他进程(如果是system_process等系统进程出问题的话,则会引起系统重启)。

做应用开发的时候,你需要了解系统的GC(垃圾回收)机制是如何运行的,Android里面使用有向图作为遍历回收内存的机制。Java将引用关系考虑为图的有向边,有向边从引用者指向引用对象。线程对象可以作为有向图的起始顶点,该图就是从起始顶点开始的一棵树,根顶点可以到达的对象都是有效对象,GC不会回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。

  因此对于我们已经不需要使用的对象,我们可以把它设置为null,这样当GC运行的时候,就好遍历到你这个对象已经没有引用,会自动把该对象占用的内存回收。我们没法像C++那样马上释放不需要的内存,但是我们可以主动告诉系统,哪些内存可以回收了。

  3、查看应用内存使用情况

  下面我们看看如何在开发过程中查看我们程序运行时内存使用情况。我们可以通过ADB的一个命令查看:

  //$package_name:应用包名
  //$pid:应用进程ID,可以用PS命令查看
  adb shell dumpsys meminfo $package_name or $pid 

  

  上面是我使用包名查看Gallery例子的内存使用情况图,里面信息很多,不过我们主要关注的是native和Davilk的使用情况。(Android2.X和Android4.X查看的信息排序是不一样的,内容差不多,不过排布有差异,我上面是4.0的截图)

Android底层内核是基于Linux的,而Linux里面相对Window来说,有一点很特别的是,会尽量使用系统内存加载一些缓存数据或者进程间共享数据。Linux本着不用白不用的原则,会尽量使用系统内存,加快我们应用的运行速度。当然,如果我们期待某个需要大内存的应用,系统也能马上释放出一定的内存使用,这是系统内部调度实现。因此严格来说,我们要准备计算Linux下某个进程内存大小比较困难。 因为有paging out to disk(换页),所以如果你把所有映射到进程的内存相加,它可能大于你的内存的实际物理大小。


  dalvik:是指dalvik所使用的内存。
  native:是被native堆使用的内存。应该指使用C\C++在堆上分配的内存。
  other:是指除dalvik和native使用的内存。但是具体是指什么呢?至少包括在C\C++分配的非堆内存,比如分配在栈上的内存。puzlle!
  Pss:它是把共享内存根据一定比例分摊到共享它的各个进程来计算所得到进程使用内存。网上又说是比例分配共享库占用的内存,也就是上面所说的进程共享问题。
  PrivateDirty:它是指非共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使你的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已。
  SharedDirty:参照PrivateDirty我认为它应该是指共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使所有共享它的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已。

  上面针对meminfo里面的信息给出解析,这些很多我是参考了网上一些文章,所以如果有理解不到位的,欢迎各位指出。

  4、程序中获取内存信息

  通过ActivityManager获取相关信息,下面是一个例子代码:

  privatevoid displayBriefMemory()  
  {     
      final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);     
      ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();    
      activityManager.getMemoryInfo(info);     
      Log.i(tag,"系统剩余内存:"+(info.availMem >> 10)+"k");    
      Log.i(tag,"系统是否处于低内存运行:"+info.lowMemory); 
      Log.i(tag,"当系统剩余内存低于"+info.threshold+"时就看成低内存运行"); 
  } 

  另外通过Debug的getMemoryInfo(Debug.MemoryInfo memoryInfo)可以得到更加详细的信息。跟我们在ADB Shell看到的信息一样比较详细。

  5、总结

今天主要是分析了如何获取我们应用的内存使用情况信息,关于这方面的信息,其实还有其他一些方法。另外还介绍APP应用的默认内存已经Android的GC回收,不过上面只是很浅薄地分析了一下,让大家有个印象。这些东西真要深入分析得花不少精力。因为我们的目的只是解决OOM问题,所以目前没打算深入分析,后面有时间进行Android系统分析的时候,我们再深入分析。下一次我们用以前写的Gallery例子讲解如何避免OOM问题,以及内存优化方法。


这篇关于Android中App可分配内存的大小的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1047533

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到

android系统源码12 修改默认桌面壁纸--SRO方式

1、aosp12修改默认桌面壁纸 代码路径 :frameworks\base\core\res\res\drawable-nodpi 替换成自己的图片即可,不过需要覆盖所有目录下的图片。 由于是静态修改,则需要make一下,重新编译。 2、方法二Overlay方式 由于上述方法有很大缺点,修改多了之后容易遗忘自己修改哪些文件,为此我们采用另外一种方法,使用Overlay方式。