![]()
Android应用的内存泄露,其实就是java虚拟机的堆内存泄漏.
当然,当应用有ndk,jni时,没有及时free,本地堆也会出现内存泄漏.
本文只是针对JVM内存泄漏应用,进行阐述分析.
1.知识储备
1.Java内存模型

相关内存对象模型,参照博客精讲Java内存模型
1) 寄存器(register)。这是最快的保存区域,这是主要由于它位于处理器内部。然而,寄存器的数量十分有限,所以寄存器是需要由编译器分配的。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹。
(2) 堆栈(stack)。android画图板在执行函数(方法)时,函数一些内部变量的存储都可以放在栈上面创建,函数执行结束的时候这些存储单元就会自动被释放掉。位于通用RAM(随机访问存储器)中。可通过它的“堆栈指针” 获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。
(3) 堆(heap)。一种通用性的内存池(也在RAM区域),堆是不连续的内存区域,堆空间比较灵活也特别大。其中保存了Java对象(对象里面的成员变量也在其中)。在堆里分配存储空间时会花掉更长的时间!也叫做动态内存分配。
(4) 静态存储(static storage)。这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM 里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java 对象本身永远都不会置入静态存储空间,随着JVM的生命周期结束而结束,即当app完全退出,他才会释放。
(5) 常数存储(constant storage)。常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。
(6) 非RAM 存储(non-storage-RAM)。若数据完全独立于一个程序之之外。其中两个最主要的例子便是“ 流式对象”和“固定对象” 。对于流式对象,对象会变成字节流,通常会发给另一台机器。而对于固定对象,对象保存在磁盘中。
2.GC回收机制
引用自
首先JVM是对堆进行回收操作.
1.JVM堆中分类
(1) 新域young generation:存储所有新成生的对象
(2) 旧域old generation:新域中的对象,经过了一定次数的GC循环后,被移入旧域
(3) 永久域PermanentGeneration:存储类和方法对象,从配置的角度看,这个域是独立的,不包括在JVM堆内。默认为4M。
2.Gc回收流程
(1) 当eden满了,触发young GC;
(2) young GC做2件事:一,去掉一部分没用的object;二,把老的还被引用的object发到survior里面,等下几次GC以后,survivor再放到old里面。
近年有许多3d游戏大作对内存容量需求不小,开启视频剪辑之类的应用程序更是能够轻松吃掉大部分运行内存,然而多数用户的主板最多只有4根内存插槽,通常内存会采用8gb*4,总共32gb。
另一种是当用户开始查看其他雇员的档案信息的时候,把存储了当前所查看的雇员档案信息的java对象结束引用,使得垃圾收集线程可以回收其所占用的内存空间,当用户再次需要浏览该雇员的档案信息的时候,重新构建该雇员的信息。
handle promotionfailure,则触发minorgc就会同时触发full gc,哪怕老年代还有很多内存,所以,最好不要这样做)。
另外,在并发收集过程中,用户线程仍然在运行,仍然产生内存垃圾,所以可能产生“浮动垃圾”,本次无法清理,只能下一次full gc才清理,因此在gc期间,需要预留足够的内存给用户线程使用。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-89859-1.html
下—次就没机会了
······总之