android heapStartSize heapMaximumSize heapGrowthLimit heapSize说明

本文详细解析了Dalvik虚拟机中内存管理的关键参数,包括heapStartingSize、heapMaximumSize及heapGrowthLimit的作用机制,并解释了这些参数如何影响Java应用程序的运行。

尊重原创作者,转载请注明出处:

http://blog.youkuaiyun.com/gemmem/article/details/12008005

dalvik/vm/Globals.java代码片段:


struct DvmGlobals {
    /*
     * Some options from the command line or environment.
     */
    char*       bootClassPathStr;
    char*       classPathStr;


    size_t      heapStartingSize;
    size_t      heapMaximumSize;
    size_t      heapGrowthLimit;

    size_t      stackSize;
    ................

    ................

    ................

heapStartingSize是进程启动时java heap的初始大小

heapMaximumSize的值必须大于heapGrowthLimit,当heapGrowthLimit值为0时,heapGrowthLimit就被赋值为heapMaximumSize。当Java堆对象总和达到heapGrowthLimit时,dalvik会抛出Error级别的异常,java app的主线程的DefaultUncaughtExceptionHandler会执行,弹出对话框提示app结束。

代码如下:dalvik/vm/alloc/Heap.cpp

/*
 * Initialize the GC heap.
 *
 * Returns true if successful, false otherwise.
 */
bool dvmHeapStartup()
{
    GcHeap *gcHeap;


    if (gDvm.heapGrowthLimit == 0) {
        gDvm.heapGrowthLimit = gDvm.heapMaximumSize;
    }



    gcHeap = dvmHeapSourceStartup(gDvm.heapStartingSize,
                                  gDvm.heapMaximumSize,
                                  gDvm.heapGrowthLimit);
    if (gcHeap == NULL) {
        return false;
    }

   .................

   .................

   .................

  dalvik.vm.heapsize这个property只对largeHeap的app起作用。当app的AndroidManifest.xml设置了大内存,heapGrowthLimit就不起作用了。

### JVM 堆内存配置分析 在给定的堆配置参数下,`target_footprint` 的变化情况以及堆内存管理行为可以通过以下几个方面来理解: #### 1. **目标足迹 (`target_footprint`)** `target_footprint` 是指 JVM 预期的目标堆大小,在动态调整堆的过程中起到重要作用。其计算方式通常基于初始堆大小、最大堆大小以及其他相关参数。 - 初始情况下,当 `Heapstartsize=16m` 和 `Heapsize=512m` 被设定时,JVM 将尝试维持一个接近于起始值(16MB)到最大值(512MB)之间的堆大小范围[^4]。 - 如果设置了 `Heapgrowthlimit=384m`,则表示堆的增长上限为 384MB,即使理论上的最大堆可以达到 512MB,实际增长不会超出该限制。 - 当前自由空间小于 `Heapminfree=2m` 或大于 `Heapmaxfree=8m` 时,触发堆收缩或扩展操作以满足需求[^4]。 因此,`target_footprint` 的变化规律主要取决于应用负载的变化程度: - 应用负载较低时,堆倾向于缩小至接近最小阈值(如 16MB 加上必要的额外缓冲区),但不低于 `Heapminfree` 所需的空间。 - 应用负载较高时,堆逐渐增大直至接近 `Heapgrowthlimit` 或者完全填满可用的最大容量(如果允许的话)。此时,`target_footprint` 更加贴近实际使用的峰值内存。 #### 2. **堆内存管理行为** ##### (1)**初始化阶段** 启动应用程序时,默认分配的堆大小由 `-Xms` 参数决定(此处对应的是 `Heapstartsize=16m`)。这意味着 JVM 开始运行时只会请求操作系统提供至少 16MB 的连续地址空间作为初始堆区域[^4]。 ```bash -Xms16m -Xmx512m ``` ##### (2)**扩展与缩减过程** 随着程序执行过程中不断生成新的对象实例,现有堆可能变得不足以容纳新增数据结构。在这种情形下,JVM 动态增加堆尺寸直到触及预设界限之一为止——要么是绝对意义上的最高限界(即 `Heapsize=512m`),要么受制于相对约束条件下的局部顶点(比如这里提到的 `Heapgrowthlimit=384m`)。 另一方面,一旦发现某些部分已经不再被任何活动引用所关联,则这部分废弃的数据会被标记清除并通过垃圾收集器回收再利用;与此同时,假如剩余空闲比例显著高于预期水平(例如超过了 `Heapmaxfree=8m` 设定的比例),那么整个堆规模也可能随之相应地下降一些单位量级以便节省资源消耗。 ##### (3)**特殊情况处理** 对于极端场景而言,诸如持续不断地创建短生命周期临时变量或者频繁发生全量扫描式的全局 GC 操作等情况均可能导致性能瓶颈甚至崩溃风险。具体表现形式包括但不限于如下几种典型错误提示信息及其背后含义解释: - `java.lang.OutOfMemoryError: Java heap space`: 表明当前可用堆已耗尽无法继续分配更多存储单元用于保存新产生的实体对象。 ```java List<String> list = new ArrayList<>(); String str = "hello"; while (true){ str += str; list.add(str); } ``` - `Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded`: 提醒开发者注意是否存在过多时间花费在垃圾清理动作上面却仅仅获得很少的有效成果产出的现象存在,这通常是由于过小的堆设置引起长期压力累积所致[^2]。 --- ###
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值