Android线性内存分配器LinearAlloc分析

本文探讨了Android Dalvik虚拟机中的线性内存分配器LinearAlloc,其主要负责类加载时的只写一次内存分配。通过分析LinearAlloc的代码,了解其简单、快速的内存分配方式,以及如何在程序运行期间提高性能,减少堆混乱和垃圾扫描。LinearAlloc从系统申请5M内存,并按线性顺序分配,每个Dalvik虚拟机实例都有一个全局的LinearAllocHdr结构体进行管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为毕业设计做Dalvik内存管理方面的优化。

这些天仔细阅读了下线性分配器LinearAlloc的代码

线性分配器代码为于android_src/dalvik/vm/目录下的

只有两个文件LinearAlloc.h和LinearAlloc.c代码很少,约800多行而已

线性分配器的目的在于简单、快速地分配只写一次(write-once)的内存(即分配并完成初始化写入后一般不会再改变,保持只读性质)

它主要用来管理Dalvik中类加载时的内存,因为类加载后通常是只读属性,而不需要去改变

且在程序的整个运行周期都是有效的,同时它还有共享的特性,一个应用加载后其它进程可以共享使用这些已加载的类从而加快程序的启动和运行速度

另外,在Java中动态分配内存是由堆来管理的,需要一个垃圾收集器来管理垃圾,对于永久存在的内存区不需要垃圾收集器的扫描清除,

所以将这些永久存在的内存块放到线性分配器中管理能很好地减少堆混乱和垃圾扫描,加快系性能

好吧,进入正题:

线性内存分配器用shmem从系统中申请一块大小为5M的内存,然后用自己的接口来管理它,提供分配和释放内存的API

它的线性在于分配内存从低地址到高地址,先分配的在前,后分配的在后

每个Dalvik虚拟机实例有个全局的LinearAllocHdr结构体来描述当前虚拟机的线性分配器

gDvm.pBootLoaderAlloc

以下是它的唯一一个数据结构

/*
 * Linear allocation state.  We could tuck this into the start of the
 * allocated region, but that would prevent us from sharing the rest of
 * that first page.
 线性分配状态,可以将它放到分配区域的前段,但是那会防碍共享它的第一页之外的页
 */
typedef struct LinearAllocHdr {
    int     curOffset;          /* offset where next data goes *///下一次分配的地址
    pthread_mutex_t lock;       /* controls updates to this struct *///用来多线程同步的锁

    char*   mapAddr;            /* start of mmap()ed region *///分配器管理的整块内存的起始地址
    int     mapLength;          /* length of region *///整块内存长或大小
    int     firstOffset;        /* for chasing through *///第一次分配的位置
	/* 描述内存中这些页的读写权限 它指向一个位图,位图中的每位为16bit,用来存放对应页写的次数*/
    short*  writeRefCount;      /* for ENFORCE_READ_ONLY */
} LinearAllocHdr;


它的主要接口如下
/*
 * 创建一个线性分配器
 */
LinearAllocHdr* dvmLinearAllocCreate(Object* classLoader);

/*
 * 销毁线性分配器
 */
void dvmLinearAllocDestroy(Object* classLoader);

/*
 * 从线性分配器中分配内存
 */
void* dvmLinearAlloc(Object* classLoader, size_t size);
/*
 * 释放线性分配器中的内存,注意它不会增加可用的线性内存,只是用来协助其它程序调试用
 */
void dvmLinearFree(Object* classLoader, void* mem);
还有一些其它的API,如
//重新分配大小来存储原来的内容
void* dvmLinearRealloc(Object* classLoader, void* mem, size_t newSize);

//使这块区域只读
INLINE void dvmLinearReadOnly(Object* classLoader, void* mem)

//全可读写
INLINE void dvmLinearReadWrite(Object* classLoader, void* mem)

//同C中的strup,用来申请内存存放str中的内容,使用完后由用户负责调用释放
char* dvmLinearStrdup(Object* classLoader, const char* str);

//调试用,用来打印内存中的内容
void dvmLinearAllocDump(Object* classLoader);

//检查从[start,start+length)这个区域是否在线性分配的已分配区间中
bool dvmLinearAllocContains(const void* start, size_t length);
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值