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应用程序被限制了内存使用上限,一般为16M或24M(具体看系统设置),当应用的使用内存超过这个上限时,就会被系统认为内存泄漏,被kill掉。


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/6347682.html,如需转载请自行联系原作者


相关文章
|
29天前
|
编解码 算法 Java
构建高效的Android应用:内存优化策略详解
随着智能手机在日常生活和工作中的普及,用户对移动应用的性能要求越来越高。特别是对于Android开发者来说,理解并实践内存优化是提升应用程序性能的关键步骤。本文将深入探讨针对Android平台的内存管理机制,并提供一系列实用的内存优化技巧,以帮助开发者减少内存消耗,避免常见的内存泄漏问题,并确保应用的流畅运行。
|
1月前
|
存储 程序员 编译器
在C语言中.如何正确地分配和释放内存docx
在C语言中.如何正确地分配和释放内存docx
17 1
|
1月前
|
存储 C++
C/C++数据类型从0到内存具体分配详解
C/C++数据类型从0到内存具体分配详解
|
1月前
关于为什么要在链表中用malloc来分配内存
关于为什么要在链表中用malloc来分配内存
|
1天前
|
测试技术 Android开发
Android App获取不到pkgInfo信息问题原因
Android App获取不到pkgInfo信息问题原因
9 0
|
5天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
5 0
|
7天前
|
缓存 移动开发 Java
构建高效的Android应用:内存优化策略
【4月更文挑战第16天】 在移动开发领域,尤其是针对资源有限的Android设备,内存优化是提升应用性能和用户体验的关键因素。本文将深入探讨Android应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。
|
24天前
|
存储 编译器 程序员
【C语言】内存的动态分配与释放
【C语言】内存的动态分配与释放
27 0
|
30天前
|
缓存 移动开发 Java
构建高效Android应用:内存优化实战指南
在移动开发领域,性能优化是提升用户体验的关键因素之一。特别是对于Android应用而言,由于设备和版本的多样性,内存管理成为开发者面临的一大挑战。本文将深入探讨Android内存优化的策略和技术,包括内存泄漏的诊断与解决、合理的数据结构选择、以及有效的资源释放机制。通过实际案例分析,我们旨在为开发者提供一套实用的内存优化工具和方法,以构建更加流畅和高效的Android应用。
|
1月前
|
监控 Java Android开发
构建高效Android应用:从内存管理到性能优化
【2月更文挑战第30天】 在移动开发领域,打造一个流畅且响应迅速的Android应用是每个开发者追求的目标。本文将深入探讨如何通过有效的内存管理和细致的性能调优来提升应用效率。我们将从分析内存泄露的根本原因出发,讨论垃圾回收机制,并探索多种内存优化策略。接着,文中将介绍多线程编程的最佳实践和UI渲染的关键技巧。最后,我们将通过一系列实用的性能测试工具和方法,帮助开发者监控、定位并解决性能瓶颈。这些技术的综合运用,将指导读者构建出更快速、更稳定、用户体验更佳的Android应用。