内存

JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆、栈和方法区。
栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放。优点:速度快。
堆(heap):用于存放由new创建的对象和数组。在堆中分配的内存,一方面由java虚拟机自动垃圾回收器来管理,另一方面还需要程序员提供修养,防止内存泄露问题。
方法区(method):又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。

Java GC

GC可以自动清理堆中不在使用(不在有对象持有该对象的引用)的对象。

在JAVA中对象如果再没有引用指向该对象,那么该对象就无从处理或调用该对象,这样的对象称为不可到达(unreachable)。垃圾回收用于释放不可到达的对象所占据的内存。

对android来说,内存使用尤为吃紧,最开始的app进程最大分配才8M的内存,渐渐增加到16M、32M、64M,但是和服务端相比还是很渺小的。如果对象回收不及时,很容易出现OOM错误。

内存泄露

什么是内存泄露?程序通过new分配内存,在使用完毕后没有释放,造成内存占用。这块内存不受GC控制,无法通过GC回收。
主要表现在:当一个对象已经不再使用,本该被回收的,但是另外一个正在使用的对象持有它的引用从而就导致对象不能被回收。这种对象存在堆内存中,就产生了内存泄漏。

危害?内存泄漏对于app没有直接的危害,即使app有发生内存泄漏的情况,也不一定会引起app崩溃,但是会增加app内存的占用。内存得不到释放,慢慢的会造成app内存溢出。解决内存泄漏目的就是防止app发生内存溢出。

内存泄露主要表现的当Activity在finish的时候,由于对象持有对Activity的引用,造成Activity没有被及时回收。总结了下大致有5种情况造成内存泄露,(1)static变量、匿名类的使用 (2)线程执行处理(3)各种监听回调处置(4)Bitmap等回收处置(5)集合类只有增操作却没有减操作。
常见情况
1)外部类持有Activity的静态引用
[java] view plaincopy
  1. public class MainActivity extends AppCompatActivity {
  2. static Activity activity;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. CommUtil commUtil = CommUtil.getInstance(this);
  8. }
[java] view plaincopy
  1. public class CommUtils {
  2. private static CommUtils instance;
  3. private Context context;
  4. private CommUtils(Context context) {
  5. this.context = context;
  6. }
  7. public static CommUtils getInstance(Context context) {
  8. if (instance == null) {
  9. instance = new CommUtils(context);
  10. }
  11. return instance;
  12. }
  13. }

2)异步执行耗时任务期间时,Thread、AsyncTask、TimeTask持有的Activty进行finish时,Activity实例不会被回收。

[java] view plaincopy
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. new AsyncTask<String, Void, String>() {
  5. @Override
  6. protected String doInBackground(String... params) {
  7. for (int i = 0; i < 15; i++) {
  8. try {
  9. Log.e("MainActivity2", "dddd" + i + MainActivity2.this.getLocalClassName());
  10. Thread.sleep(1000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. return null;
  16. }
  17. @Override
  18. protected void onPostExecute(String s) {
  19. super.onPostExecute(s);
  20. }
  21. }.execute();
  22. }

3)Handler内部类造成内存泄露。

Handler为非静态内部类时会隐式持有当前activity引用。当Activity被 finish()时,若Handler有未处理完或延迟的消息(主要是Handler牵扯到线程问题),会造成activity不能被回收。
[java] view plaincopy
  1. MyHandler myHandler = new MyHandler();
  2. @Override
  3. protected void onCreate(@Nullable Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. myHandler.postDelayed(new Runnable() {
  6. @Override
  7. public void run() {
  8. }
  9. }, 50 * 1000);
  10. }
  11. class MyHandler extends Handler {
  12. @Override
  13. public void handleMessage(Message msg) {
  14. super.handleMessage(msg);
  15. }
  16. }

解决办法:在Activity生命周期结束前,确保Handler移除消息(mMyHanlder.removeCallbacksAndMessages(null);)或者使用静态Handler内部类。

如:使用了弱引用替代强引用.
[java] view plaincopy
  1. static MyHandler myHandler;
  2. @Override
  3. protected void onCreate(@Nullable Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. myHandler = new MyHandler(this);
  6. }
  7. static class MyHandler extends Handler {
  8. WeakReference<Activity> mActivityReference;
  9. MyHandler(Activity activity) {
  10. mActivityReference = new WeakReference<Activity>(activity);
  11. }
  12. @Override
  13. public void handleMessage(Message msg) {
  14. final Activity activity = mActivityReference.get();
  15. if (activity != null) {
  16. //....
  17. }
  18. }
  19. }
建议熟悉下:强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)、虚引用(PhantomReference)
4)匿名内部类的使用。
[java] view plaincopy
  1. public class DemoActivity extends AppCompatActivity {
  2. Runnable runnable = new Runnable() {
  3. @Override
  4. public void run() {
  5. }
  6. };

runnable默认会持有DemoActivity的引用。若Activity被finish的时候,如线程在使用runnable,则会造成内存泄露。

5)构造Adapter时没有使用缓存的 convertView
[java] view plaincopy
  1. public View getView(int position, View convertView, ViewGroup parent) {
  2. View view = null;
  3. if (convertView == null)
  4. convertView = View.inflate(this, R.layout.item_layout, false);
  5. view = convertView;
  6. return view;
  7. }
6) 当使用了BraodcastReceiver、Cursor、Bitmap等资源时,若没有及时释放,则会引起内存泄漏。
7)集合类的不当使用。

更多内存泄露可以通过检测工具发现。检测工具主要有MAT、Memory Monitor 、Allocation Tracker 、Heap Viewer、LeakCanary

内存溢出

什么是内存溢出?out of memory。 程序向系统申请的内存空间超出了系统能给的。内存泄露很容易引起OOM。

内存抖动

内存抖动是指在短时间内有大量的对象被创建或者被回收的现象,主要是循环中大量创建、回收对象。这种情况应当尽量避免。

Android之内存泄露、内存溢出、内存抖动分析相关推荐

  1. drools规则引擎因为内存泄露导致的内存溢出

    进入这个问题之前,先了解一下drools: 在很多行业应用中比如银行.保险领域,业务规则往往非常复杂,并且规则处于不断更新变化中,而现有很多系统做法基本上都是将业务规则绑定在程序代码中. 主要存在的问 ...

  2. 转载浅谈MFC内存泄露检测及内存越界访问保护机制

    2019独角兽企业重金招聘Python工程师标准>>> 本文所有代码均在VC2008下编译.调试.如果您使用的编译器不同,结果可能会有差别,但本文讲述的原理对于大部分编译器应该是相似 ...

  3. JavaScript内存泄露,闭包内存泄露如何解决

    转载于:JavaScript内存泄露,闭包内存泄露如何解决 - 一粒一世界 - 博客园 JavaScript 内存泄露的4种方式及如何避免 简介 什么是内存泄露? JavaScript 内存管理 Ja ...

  4. 内存泄露和溢出的区别_Java 中的内存溢出和内存泄露是什么?我给你举个有味道的例子?...

    JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看. 内存泄漏 & 内存溢出 1. 内存泄漏(memory leak ) 申请了内存用完了不释放,比如一共有 1024M ...

  5. java 多线程 内存泄露_关于内存泄露的总结

    大致先分为五个小模块: 1.什么是内存泄漏 2.有哪些情况会导致内存泄漏切如何解决 3.如何检测内存泄漏 4.Java得基本数据类型和占用字节 5.什么是内存溢出和解决办法 一.什么是内存泄漏(Mem ...

  6. java 匿名内部类内存泄露_Android 常见内存泄露 解决方案

    前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...

  7. Qt中内存泄露和半自动内存管理

    Qt中帮程序员做了一些内存回收的事情,但正因为这些反而让对此不熟悉的人会屡屡犯错. 收录一篇不错的文章: 在C++中学习过程中,我们都知道: delete 和 new 必须 配对使用(一 一对应):d ...

  8. java thread 内存泄露_Java ThreadLocal 内存泄露问题分析及解决方法。

    前言 在分析ThreadLocal导致的内存泄露前,需要普及了解一下内存泄露.强引用与弱引用以及GC回收机制,这样才能更好的分析为什么ThreadLocal会导致内存泄露呢?更重要的是知道该如何避免这 ...

  9. java中为什么还要防止内存泄露_JAVA防止内存的泄漏什么意思,内存还能泄露?...

    展开全部 尽管java虚拟机和62616964757a686964616fe59b9ee7ad9431333166353066垃圾回收机制管理着大部分的内存事务,但是在java软件中还是可能存在内存泄 ...

  10. win11内存泄露怎么办 Windows11内存泄露的解决方法

    最近很多使用Win11系统的小伙伴在打开系统进程的时候发现桌面窗口管理器占用了大量的内存,严重造成了内存泄露,那么遇到这种情况要怎么办呢?下面就就和小编一起来看看有什么解决方法吧.更多windows1 ...

最新文章

  1. 【OpenCV 4开发详解】均值滤波
  2. Android开发者指南(18) —— Web Apps Overview
  3. 使用SC命令时注意事项
  4. 【深度学习】面向医学图像的病灶分割调研(三)
  5. 湖南大学第十六届程序设计竞赛 B Yuki with emofunc and playf 同余最短路
  6. 给 axios 和 redux-axios-middleware 添加finally方法 的使用心得
  7. 微信带翅膀昵称ʚɞ,这也太可了吧
  8. HTML+CSS制作3D旋转相册
  9. 苹果手机说明书_知科技新鲜事 | 华为Mate40系列手机壳曝光:3.5mm耳机孔
  10. 多层陶瓷电容器用处_具有综合优异电卡性能的无铅多层陶瓷电容器研究新进展...
  11. 常见NoSQL数据库概述
  12. 【JAVA程序设计】(C00011)基于ssm的企业OA(考勤)管理系统
  13. redis数据一致性
  14. 一意孤行亚马逊----一个钓鱼疯子的巴西亚马逊之行( 11.9月 27日 最惨的一天 ) 作者:咸水鱼...
  15. pageoffice在线打开word文件加盖电子印章
  16. ems苹果专线投递速度_“高功率脉冲磁控溅射”新工艺:苹果 iPhone 12 Pro 金色版图赏 - 苹果,iPhone...
  17. 基于vue-cli快速构建
  18. 激光雷达赛道“白刃战”?硅光芯片级FMCW技术进入量产周期
  19. 恩格尔注塑机数据采集
  20. 现在进行时的stem课堂设计

热门文章

  1. 并发编程-02并发基础CPU多级缓存和Java内存模型JMM
  2. Oracle实例迁移_真实场景实操
  3. 交叉熵损失函数分类_交叉熵损失函数
  4. html2Escape js 转义
  5. 解决 org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does no
  6. tomcat8+在maven中热部署
  7. Java中如何引用另一个类里的集合_【18期】Java序列化与反序列化三连问:是什么?为什么要?如何做?...
  8. 数据结构实验之栈与队列五:下一较大值(一)
  9. 面试题整理 2:求链表倒数第 k 个结点
  10. 《深度探索C++对象模型》--1 关于对象