摘要:本文将带你了解Android应用开发之遇到Android内存泄漏问题的分析和解决方法,希望本文对大家学Android有所帮助。
本文将带你了解Android应用开发之遇到Android内存泄漏问题的分析和解决方法,希望本文对大家学Android有所帮助。
内存分配
Java与c++之间有一堵内存动态分配和垃圾收集技术围成的“高墙”,墙外面的人像进去,墙里面的人去想出来。
c++是对象实例没有指针指向它,被孤立,导致内存泄露,java是没用的对象实例还有多余的引用,GC不能回收。
JVM内存运行图
共享区域
方法区( Method Area):存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译编译后的代码。
堆(Heap):存放java几乎所有对象实例 ,JIT除外。如果对象需要的内存不够,OutOfMemoryError异常。
隔离区域
虚拟机栈(VM Stack):方法执行的内存模型,用于存储方法入口、局部变量表、操作数栈、动态连接。如果栈深度大于虚拟机的栈深,抛出StackOverflowError异常,如果对象实例对象需要的内存不够,抛出OutOfMemoryError异常。
本地方法栈(Native Method Stack): 和VM Static 差不多的作用。只是虚拟机是native方法的内存模型(c/c++方法)。
程序计数器(Program Counter Register):存放线程的行号指示器,每个线程都有自己的独立的计数器。
android虚拟机
GG过程
长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java中内存泄漏的发生场景。
对于不同的语言平台来说,进行标记回收内存的算法是不一样的,像 Android(Java)则采用 GC-Root 的标记回收算法(Mark sweap)。下面这张图就展示了 Android 内存的回收管理策略(图来自Google 2011的IO大会)
图中的每个圆节点代表对象的内存资源,箭头代表可达路径。当圆节点与 GC Roots 存在可达路径时,表示当前资源正被引用,虚拟机是无法对其进行回收的(如图中的黄色节点)。反过来,如果圆节点与 GC Roots 不存在可达路径,则意味着这块对象的内存资源不再被程序引用,系统虚拟机可以在 GC 过程中将其回收掉。
深入JVM虚拟机(三) Java GC垃圾收集 https://blog.csdn.net/yuan_xw/article/details/51434007
GC算法
1.引用计数法
2、标记清除法
4、复制算法
5、分代思想:
常见内存泄漏原因
1.非静态内部类的静态实例 public class SecondActivity extends AppCompatActivity { private static Object inner; private Button button;
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.bt_next); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {createInnerClass();finish(); } });} void createInnerClass() { class InnerClass { } inner = new InnerClass();//1}
}
不要使用
2.匿名内部类的静态实例
public class AsyncTaskActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
button = (Button) findViewById(R.id.bt_next);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startAsyncTask();
finish();
}
});
}
void startAsyncTask() {
new AsyncTask
内存泄漏的的分析
1.使用 adb shell dumpsys meminfo [PackageName],可以打印出指定包名的应用内存信息
localhost:jdk7u-dev li$ adb shell dumpsys meminfo cn.babyfs.android
Applications Memory Usage (in Kilobytes):
Uptime: 188198513 Realtime: 458787859
* MEMINFO in pid 26780 [cn.babyfs.android] *
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
——————————————
Native Heap 16970 16776156 0 32128 14411 17716
Dalvik Heap 42663 38076 4448 0 55728 39344 16384
Dalvik Other 8273 8264 0 0
Stack 1816 1816 0 0
Ashmem238120 0 0
Gfx dev 21244 21244 0 0
Other dev 70 0 68 0
.so mmap 8305460 5232 98
.jar mmap 4 0 0 0
.apk mmap 34883 22316 12196 0
.ttf mmap603 0188 0
.dex mmap 7153 6260772 0
.oat mmap 5801 0648 0
.art mmap 4331 2096972 3
Other mmap766 4684 1
EGL mtrack 11152 11152 0 0
GL mtrack 5576 5576 0 0
Unknown 7891 7888 0 6
TOTAL177847142048 25364108 87856 53755 34100
App Summary
Pss(KB)
——
Java Heap: 41144
Native Heap: 16776
Code: 48072
Stack: 1816
Graphics: 37972
Private Other: 21632
System: 10435
?1TOTAL:177847 TOTAL SWAP PSS:108
Objects
Views:224ViewRootImpl: 4
AppContexts: 5 Activities: 1
Assets: 18 AssetManagers: 3
Local Binders:100 Proxy Binders: 38
Parcel memory: 24Parcel count: 96
Death Recipients: 4OpenSSL Sockets: 0
WebViews: 0
SQL
MEMORY_USED:369
PAGECACHE_OVERFLOW:105 MALLOC_SIZE: 62
DATABASES
pgsz dbszLookaside(b) cache Dbname
4 24 61 11/40/7 /data/user/0/cn.babyfs.android/databases/babyfs
1 3 0/0/0 (attached) temp
4 24 72591/143/8 /data/user/0/cn.babyfs.android/databases/statistic
1 3 0/0/0 (attached) temp
4 20 48 12/30/9 /data/user/0/cn.babyfs.android/databases/tls_sdk.db
Asset Allocations
zip:/data/app/cn.babyfs.android-1/base.apk:/assets/ca.crt: 1K
2.使用 adb shell dumpsys activity [PackageName],可以打印出指定包名的应用acitivity信息
3.Android studio profiler
Heap类型分为:
App Heap – 当前App使用的Heap
Image Heap – 磁盘上当前App的内存映射拷贝
Zygote Heap – Zygote进程Heap(每个App进程都是从Zygote孵化出来的, 这部分基本是framework中的通用的类的Heap)
Class List View – 类列表方式
Package Tree View – 根据包结构的树状显示
紧接着下面的表名:
列名 说明
Class Name Heap中的所有Class
Total Count 内存中该类这个对象总共的数量
Heap Count 堆内存中这个类对象的个数
Sizeof 每个该实例占用的内存大小
Shallow Size 所有该类的实例占用的内存大小
Retained Size所有该类对象被释放掉,会释放多少内存
接下来是B区域
列名 说明
Instance 该类的实例
Depth深度, 从任一GC Root点到该实例的最短跳数
Dominating Size 该实例可支配的内存大小
C区域则描述的是B中实例具体被引用信息。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注移动开发之Android频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号