昨天用Gallery做了一个图片浏览选择开机画面的功能,当我加载的图片多了就出现OOM问题。以前也出现过这个问题,那时候并没有深究。这次打算好好分析一下Android的内存机制。

因为我以前是做VC++开发,因此对C++在Window下的内存机制还是比较了解。不过转到Android后,一直都没有刻意去处理内存问题,因 为脑子里一直想着Java的GC机制。不过现在想想,自己对Android的GC和内存管理并不了解,自己写的代码在内存哪里运行都不清楚,心里不淡定 啊。

毕竟我以前写C++的时候,什么时候在哪里申请内存,什么时候释放内存,会不会栈溢出或者堆内存泄露都了如指掌。言归正传,今天打算先了解一下Android的堆和栈跟C++有何区别。

1、dalvik的Heap和Stack


这里说的只是dalvik  java部分的内存,实际上除了dalvik部分,还有native。这个以后再说。

下面针对上面列出的数据类型进行说明,只有了解了我们申请的数据在哪里,才能更好掌控我们自己的程序。

2、对象实例数据


实际上是保存对象实例的属性,属性的类型和对象本身的类型标记等,但是不保存实例的方法。实例的方法是属于数据指令,是保存在Stack里面,也就是上面表格里面的类方法。

对象实例在Heap中分配好以后,会在stack中保存一个4字节的Heap内存地址,用来查找对象的实例。因为在Stack里面会用到Heap的实例,特别是调用实例的时候需要传入一个this指针。

3、方法内部变量


类方法的内部变量分为两种情况:简单类型保存在Stack中;对象类型在Stack中保存地址,在Heap 中保存值。

4、非静态方法和静态方法


非静态方法有一个隐含的传入参数,这个参数是dalvik虚拟机传进去的,这个隐含参数就是对象实例在Stack中的地址指针。因此非静态方法(在 Stack中的指令代码)总是可以找到自己的专用数据(在Heap 中的对象属性值)。当然非静态方法也必须获得该隐含参数,因此非静态方法在调用前,必须先new一个对象实例,获得Stack中的地址指针,否则 dalvik虚拟机将无法将隐含参数传给非静态方法。

静态方法没有隐含参数,因此也不需要new对象,只要class文件被ClassLoader load进入JVM的Stack,该静态方法即可被调用。所以我们可以直接使用类名调用类的方法。当然此时静态方法是存取不到Heap 中的对象属性的。

5、静态属性和动态属性


静态属性是保存在Stack中的,而不同于动态属性保存在Heap 中。正因为都是在Stack中,而Stack中指令和数据都是定长的,因此很容易算出偏移量,所以类方法(静态和非静态)都可以访问到类的静态属性。也正 因为静态属性被保存在Stack中,所以具有了全局属性。

6、总结


Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和 multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事 先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较 慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些 基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。

对比上面的解析可以看出,其实Java处理Heap和Stack的大致原理跟C++是一样的。只是多了一个内存回收机制,让程序员不用主动调用delete释放内存。就像在C++里面,一般使用new申请的内存才会放到堆里面,而一般的临时变量都是放到栈里面去。

今天主要是说说Android的dalvik里面的堆和栈的区别,以及存放哪些数据。粗了dalvik内存外, Android还有个native内存的概念。这个下次会继续讲解。我刚开始分析Android的内存机制,如果阅读过程中发现任何问题请留言指出,谢谢!


想了解最新移动开发资讯,最前沿的移动开发技术吗?微信搜“eoe”或扫描二维码关注eoe公众账号即可。公众账号支持绑定社区、签到及Ping功能。您也可以下载eoe客户端,随时随地看资讯读博客。

【Android内存机制分析】了解Android堆和栈的更多相关文章

  1. Android内存机制分析1——了解Android堆和栈

    //----------------------------------------------------------------------------------- Android内存机制分析1 ...

  2. Android内存机制分析2——分析APP内存使用情况

    上面一篇文章说了Android应用运行在dalvik里面分配的堆和栈内存区别,以及程序中什么代码会在哪里运行.今天主要是讲解一下Android里面如何分析我们程序内存使用情况.以便后续可以分析我们程序 ...

  3. 【转】Android内存机制分析1——了解Android堆和栈

    昨天用Gallery做了一个图片浏览选择开机画面的功能,当我加载的图片多了就出现OOM问题.以前也出现过这个问题,那时候并没有深究.这次打算好好分析一下Android的内存机制. 因为我以前是做VC+ ...

  4. Android内存机制分析——堆和栈

    昨天用Gallery做了一个图片浏览选择开机画面的功能,当我加载的图片多了就出现OOM问题.以前也出现过这个问题,那时候并没有深究.这次打算好好分析一下Android的内存机制. 因为我以前是做VC+ ...

  5. 【转】Android内存机制分析2——分析APP内存使用情况

    上面一篇文章说了Android应用运行在dalvik里面分配的堆和栈内存区别,以及程序中什么代码会在哪里运行.今天主要是讲解一下Android里面如何分析我们程序内存使用情况.以便后续可以分析我们程序 ...

  6. 【Android】Android内存机制,了解Android堆和栈

    1.dalvik的Heap和Stack 这里说的只是dalvik java部分的内存,实际上除了dalvik部分,还有native.     下面针对上面列出的数据类型进行说明,只有了解了我们申请的数 ...

  7. Android 内存管理分析(四)

    尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...

  8. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  9. android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...

随机推荐

  1. Nginx负载均衡反向代理

    http{ upstream test.com { server 118.118.66.88:8080; } server { listen 80; server_name www.test.com; ...

  2. 删除 java代码中所有的注释

    删除 java代码中所有的注释.java public class CleanCommons { private static Pattern pattern = Pattern.compile(&q ...

  3. Angungular.js 的过滤器&工具方法

    字母大小写 数字 货币 截取字符串 截取数组 用JS操作 ----------------------------------------------------------------------- ...

  4. Thinkphp5.0 模型hasOne、hasMany、belongsTo详解

    ThinkPHP5有关联模型的操作,但有部分初学者对数据表中常见的几种表与表的关系还存在着问题,所以使用不好关联查询. 这里将hasOne.hasMany.belongsTo进行一个详细举例说明. 首 ...

  5. 卡特兰数(catalan)总结

    卡特兰数的公式 递推公式1:$f(n)=\sum \limits_{i=0}^{n-1}f(i)*f(n-i-1)$ 递推公式2:$f(n)=\frac{f(n-1)*(4*n-2)}{n+1}$ 组 ...

  6. chrome浏览器 新打开的页面覆盖当前页面

    chrome浏览器  本应该新打开一个页面,却覆盖了当前页面. 解决办法:使用鼠标中键打开一次,后续即可正常使用.

  7. IDG资本全球拼图:近10年揽26家独角兽,最敢出手VC再造"VC+"

    IDG资本全球拼图:近10年揽26家独角兽,最敢出手VC再造"VC+" 2017-04-01 15:33   两天前,IDG资本合伙人过以宏提出的“VC+”,又有了新的内涵——全球 ...

  8. 微信小程序制作下来菜单

    wxml: <view class="phone_one" bindtap="clickPerson"> <view class=" ...

  9. 【JZOJ5086】【GDOI2017第四轮模拟day1】数列 折半搜索

    题面 有一个长度为n 的排列,现在有一些位置的数已经模糊不清了,你只知道这个排列的逆序对个数是K,你能计算出总共有多少可能的排列吗? 对于100% 的数据,n <=10^3,K<=10^9 ...

  10. Django 配置MySQL数据库 mysql

    Django 配置MySQL数据库 在settings.py中配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # ...