davlik虚拟机内存管理之一——内存分配
转载自http://www.miui.com/thread-74715-1-1.html
dalvik虚拟机是Google在Android平台上的Java虚拟机的实现,内存管理是dalvik虚拟机中的一个重要组件。
从概念上来说,内存管理的核心就是两个部分:分配内存和回收内存。Java语言使用new操作符来分配内存,但是与C/C++等语言不同的是,Java语言并没有提供任何操作来释放内存,而是通过一种叫做垃圾收集的机制来回收内存。对于内存管理的实现,我们通过三个方面来加以分析:内存分配,内存回收和内存管理调试。本文就是这一系列文章的第一篇,分析dalvik虚拟机是如何分配内存的。
1. 对象布局
内存管理的主要操作之一是为Java对象分配内存,Java对象在虚拟机中的内存布局如下:

所有的对象都有一个相同的头部clazz和lock。
(1)clazz:clazz指向该对象的类对象,类对象用来描述该对象所属的类,这样可以很容易的从一个对象获取该对象所属的类的具体信息。
(2)lock:是一个无符号整数,用以实现对象的同步。
(3)data:存放对象数据,根据对象的不同数据区的大小是不同的。
2. 堆
堆是dalvik虚拟机从操作系统分配的一块连续的虚拟内存。heapBase是堆的起始地址,heapLimit是堆的最大地址,堆大小的最大值可以通过-Xmx选项或dalvik.vm.heapsize指定。在原生系统中,一般dalvik.vm.heapsize值是32M,在MIUI中我们将其设为64M。
3. 堆内存位图
在虚拟机中维护了两个对应于堆内存的位图,称为liveBits和markBits。
在对象布局中,我们看到对象最小占用8个字节。在为对象分配内存时要求必须8字节对齐。这也就是说,对象的大小会调整为8字节的倍数。比如说一个对象的实际大小是13字节,但是在分配内存的时候分配16字节。因此所有对象的起始地址一定是8字节的倍数。堆内存位图就是用来描述堆内存的,每一个bit描述8个字节,因此堆内存位图的大小是堆的64分之一。对于MIUI的实现来说,这两个位图各占1M。
liveBits的作用是用来跟踪堆中已分配的内存,每分配一个对象时,对象的内存起始地址对应于位图中的位被设为1。在下一篇垃圾收集中我们会进一步的分析liveBits和markBits这两个位图的作用。
4. 堆的内存管理
在dalvik虚拟机实现中,是通过底层的bionic C库的malloc/free操作来分配/释放内存的。bionic C库的malloc/free操作是基于DougLea的实现(dlmalloc),这是一个被广泛使用,久经考验的C内存管理库,本文不展开dlmalloc的具体实现,有兴趣的读者请参考http://g.oswego.edu/dl/html/malloc.html。
5. dvmAllocObject
在dalvik虚拟机中,new操作符最终对应dvmAllocObject这个C函数。下面通过伪码的形式列出dvmAllocObject的实现。
Object*dvmAllocObject(ClassObject *clazz, int flags) {
n = get object size from class object clazz
first try: allocate n bytes from heap
if first try failed {
run garbage collector without collecting soft references
second try: allocate n bytes from heap
}
if second try failed {
third try: grow the heap and allocate n bytes from heap
(注释:堆是虚拟内存,一开始并未分配所有的物理内存,只要还没有达到虚拟内存的最大值,可以通过获取更多物理内存的方式来扩展堆)
}
if third try failed {
run garbage collector with collecting soft references
fourth try: grow the heap and allocate n bytes from heap
}
if fourth try failed, return null pointer, dalvik vm will abort
}
可以看出,为了分配内存,虚拟机尽了最大的努力,做了四次尝试。其中进行了两次垃圾收集,第一次不收集SoftReference,第二次收集SoftReference。从中我们也可以看出垃圾收集的时机,实质上在dalvik虚拟机实现中有3个时机可以触发垃圾收集的运行:
(1)程序员显式的调用System.gc()
(2)内存分配失败时
(3)如果分配的对象大小超过384KB,运行并发标记(concurrent mark),在下一篇文章中会介绍什么是并发标记
6.小结
在dalvik虚拟机中,内存分配操作的流程相对比较简单直观,从一个堆中分配可用内存,分配失败时触发垃圾收集,接下来的文章中我们仔细分析dalvik虚拟机的垃圾收集。
davlik虚拟机内存管理之一——内存分配的更多相关文章
- Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇分享了JVM及其启动流程,今天介绍一下JVM内部的一些区域,以及具体的区域在运行 ...
- SAP专家培训之Netweaver ABAP内存管理和内存调优最佳实践
培训者:SAP成都研究院开发人员Jerry Wang 1. Understanding Memory Objects in ABAP Note1: DATA itab WITH HEADER LINE ...
- 【深入理解Java虚拟机】自动内存管理机制——内存区域划分
Java与C++之间有一堵有内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来.C/C++程序员既拥有每一个对象的所有权,同时也担负着每一个对象生 ...
- JVM堆内存管理与自定义分配参数详解
堆内存模型: 在Java中,堆被划分成两个不同的区域:新生代(Young),老年代(Old).而Permanent属于永久代(方法区),不属于堆内存.新生代又被分为了三个区域:Eden,from s ...
- STL内存管理器的分配策略
STL提供了很多泛型容器,如vector,list和map.程序员在使用这些容器时只需关心何时往容器内塞对象,而不用关心如何管理内存,需要用多少内存,这些STL容器极大地方便了C++程序的编写.例如可 ...
- java的内存管理 对象的分配与释放
分配 程序员通过new为每个对象申请内存空间(基本类型除外),所有对象都在堆中分配空间:释放:对象的释放是由垃圾回收机制决定和执行的. Java内存分为两种:栈内存和堆内存 (1)在函数中定义的基本类 ...
- Android 之 内存管理-查看内存泄露(三)
概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...
- JVM自动内存管理-Java内存区域与内存溢出异常
摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...
- Delphi的内存管理及内存泄露问题 FastMM4
这几天因为一个程序长时间运行出现比较严重的内存泄露问题,开始关注了一下内存管理方面的东西,以前也注意内存管理,创建了对象及时释放,但总有忘了处理的情况. 在Delphi中没有自动回收机制,所以一定要及 ...
随机推荐
- 如何在datagridview 的head上绘制一个全选按钮
winform的项目中,经常要用到datagridview控件,但是为控件添加DataGridViewCheckBoxColumn来实现数据行选择这个功能的时候,经常需要提供全选反选功能,如果不重绘控 ...
- springmvc 配置直接访问页面
<mvc:view-controller path="/" view-name="/home"/> 在mvc中配置,访问路径就可以了
- android webview 漏洞背后的节操
by superhei 2013/09/06 [注:本文提到的都是我个人的观点,该行为也是私人行为,与任何组织.公司无关.另:水军请自重!] 一.前言 这两天,一个2+年前的android web ...
- 1968: [Ahoi2005]COMMON 约数研究
#include<cstdio> #include<iostream> #define M 1000008 using namespace std; long long tot ...
- Sticks(poj1011/uva307)
题目大意: 乔治有一些碎木棒,是通过将一些相等长度的原始木棒折断得到的,给出碎木棒的总数和各自的长度,求最小的可能的原始木棒的长度:(就是将一些正整数分组,每组加起来和相等,使和尽可能小) 一开始做p ...
- WP8.1 Study2:MapControl控件的应用
总的界面布局如下:
- 五大要求让BPM与企业对接
BPM(即业务流程管理)在中国已经有多年的发展历史,但人们经常提到的还是企业对流程的迫切需要,鲜有人讨论什么样的企业才能实施BPM,或者换句话说BPM的本身对企业有什么要求.不是所有的工作都适合BPM ...
- MyEclipse取消验证Js的两种方法
MyEclipse取消验证Js的两种方法 作者: 字体:[增加 减小] 类型:转载 通过js写一个web工程的相关页面时感觉很卡,修改内存也不行下面有两种解决方法,大家可以尝试下 前言:有时我们通过j ...
- 预写式日志WAL
Chapter 25. 预写式日志(Write-Ahead Logging (WAL)) Table of Contents 25.1. WAL 的好处 25.2. WAL 配置 25.3. 内部 预 ...
- SharePoint 2010 BCS - 简单实例(一)数据源添加
博客地址 http://blog.csdn.net/foxdave 本篇基于SharePoint 2010 Foundation. 我的数据库中有一个病人信息表Patient,现在我就想把这个表中的数 ...