转自:http://blog.csdn.net/u011506413/article/details/50965435

现在真实测试结果:  

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可分配内存的大小(转)的更多相关文章

  1. Android中App可分配内存的大小

    现在真实测试结果: 1,为了搞清楚每个应用程序在Android系统中最多可分配多少内存空间,我们使用了真机进行测试,测试机型为魅族MX4 Pro,3G内存. 测试方法是直接申请一块较大的内存空间,看应 ...

  2. Android 中对于图片的内存优化方法

    Android 中对于图片的内存优化方法,需要的朋友可以参考一下     1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFact ...

  3. Virtualbox修改虚拟机分配内存的大小

    起因:因为虚拟机刚开始分配的内存太小,导致太卡, 解决方法:修改虚拟机分配内存的大小 方法一:必须在关闭ubuntu的前提下进行,否则无法修改 点击设置 系统选项 主板中的内存大小 之后开启即可 方法 ...

  4. Android中使用Handler造成内存泄露的分析和解决

    什么是内存泄露?Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向 ...

  5. Android中使用Handler造成内存泄露

    1.什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用 ...

  6. Android中获取应用程序(包)的大小-----PackageManager的使用(二)

    通过第一部分<<Android中获取应用程序(包)的信息-----PackageManager的使用(一)>>的介绍,对PackageManager以及 AndroidMani ...

  7. Android中app卡顿原因分析示例

    在知乎回答了一个“为什么微博的app在iPhone比Android上流畅”的问题.后面部分是一个典型的动画卡顿的性能分析过程,因此帖在这里.有编程问题可以在这里交流.知乎链接. =========== ...

  8. Android 中 Handler 引起的内存泄露

    在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://w ...

  9. 抓包工具Fidder详解(主要来抓取Android中app的请求)

    今天闲着没吊事,来写一篇关于怎么抓取Android中的app数据包?工欲行其事,必先利其器,上网google了一下,发现了一款神器:Fiddler,这个貌似是所有软件开发者必备神器呀!这款工具不仅可以 ...

随机推荐

  1. EventBus总结(原)

    1.EventBus的作用 EventBus is a publish/subscribe event bus for Android and Java. EventBus可以被用来在各种自定义的监听 ...

  2. 六、SpringBoot配置@ConfigurationProperties与@Value区别

    1.@Value的使用 三种用法 // ${key} 从环境变量.配置文件中取值 @Value("${person.last-name}") private String last ...

  3. 微信小程序 textarea的placeholder层级过高 在弹层之上 bug解决方法

    微信小程序textarea的placeholder的层级一直都是一个神坑, 我们是没有办法将我们的弹层加大层级去盖过placeholder的, 所以要解决这个问题只能从另外的角度找思路 我的思路是 : ...

  4. ThreadLocal内存泄漏

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11421437.html 内存泄漏 内存泄漏是指不再使⽤的对象⽆法得到及时的回收,持续占⽤内存空间,从⽽ ...

  5. ICU lirary DownLoad

    { //https://github.com/unicode-org/icu }

  6. CSS 布局 - Overflow

    CSS 布局 - Overflow CSS overflow 属性用于控制内容溢出元素框时显示的方式. 这里的文本内容是可以滚动的,滚动条方向是垂直方向.dd马达价格 这里的文本内容是可以滚动的,滚动 ...

  7. hdu 6092 Rikka with Subset (集合计数,01背包)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  8. 洛谷P2786 英语1(eng1)- 英语作文

    题目背景 蒟蒻HansBug在英语考场上,挠了无数次的头,可脑子里还是一片空白. 题目描述 眼下出现在HansBug蒟蒻面前的是一篇英语作文,然而智商捉急的HansBug已经草草写完了,此时 他发现离 ...

  9. POJ 2528(线段树+离散化+特殊离散化)网上博客很少有人真正写对!!! 是POJ数据太水...

    Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...

  10. Java中如何修改Jar中的内容

    一.摘要 好长时间没写blog了,之前换了一家公司.表示工作更有战斗力了,可惜就是没时间写文章了.在这段时间其实是遇到很多问题的,只是都是记录下来,并没有花时间去研究解决.但是这周遇到这个问题没办法让 ...