欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

Android优化笔记--内存优化

程序员文章站 2022-06-22 08:11:16
内存介绍内存优化,首先解释一下什么是内存,很多同学常常只是在开发应用,说到内存,感到这个概念很“飘”,因为涉及并不太多;内存: 它是外存与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存(Memory)也被称为内存储器和主存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,操作系统就会把需要运算的数据从内存调到CPU中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算......

内存介绍       

内存优化,首先解释一下什么是内存,很多同学常常只是在开发应用,说到内存,感到这个概念很“飘”,因为涉及并不太多;内存: 它是外存与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存(Memory)也被称为内存储器和主存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,操作系统就会把需要运算的数据从内存调到CPU中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行;

Android 内存优化原因

       为了防止Android的内存溢出,内存溢出发生的条件: Android的虚拟bai机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M。因此所能利用的内存空间是有限的。如果内存占用超过了一定的水平就会出现OutOfMemory的错误;

  什么情形会导致内存不够用?
  比如:2.1 由于程序的失误,长期保持某些资源(如Context)的引用,造成内存泄露,资源造成得不到释放。 2.2 保存了多个耗用内存过大的对象(如Bitmap),造成内存超出限制。

 简单看一下Java中内存分布

Android优化笔记--内存优化

       方法区:主要存储虚拟机加载的类信息,常量,静态变量,及时编译器编译后的代码等数据。内存优化时这一部分主要考虑是不是加载了很多不必要的第三方库。这部分的内存减少主要是常量池的回收和类的卸载(类卸载条件:无引用,类加载器可卸载)
      堆:几乎所有的对象都在这个区域产生,该区域属于线程共享的区域,所以写代码时更要注意多线程安全。这个内存区域的大小变化主要是对象的创建和回收,比如:如果短时间内有大量的对象创建和回收,可能会造成内存抖动,如果对象创建之后一直回收不掉,则会导致内存泄漏,严重的内存泄漏会导致频繁的gc,从而是界面卡顿。
      虚拟机栈:这个区域描述的是java方法执行的内存模型,我们常说的方法栈的入栈就是将方法的栈帧存储到虚拟机栈,这个区域是线程私有的,其生命周期就是线程的生命周期。也就是说每个线程都会有,默认一个线程的线程栈大小是1M,这不包括在方法中产生的其他对象的大小。这一块我们能控制的就是线程的数量,特别是程序中没有使用线程池或者使用的多个第三方库都带有线程池的情况。
      本地方法栈:同虚拟机栈的作用非常类似,是为虚拟机执行native方法服务的,所以需要注意的地方也和虚拟机栈一样,特别是使用了第三方so的情况;
程序计数器:当前线程执行的虚拟机字节码的行号记录器,占用的内存较小,可以不考虑;

内存限制
   Android是基于Linux系统的,android中的进程分为两种:
  1.native进程:采用C/C++实现,不包含dalvik实例的linux进程,/system/bin/目录下面的程序文件运行后都是以native进程形式存在的;
  2.java进程:实例化了dalvik虚拟机实例的linux进程,进程的入口main函数为java函数。dalvik虚拟机实例的宿主进程是fork()系统调用创建的linux进程,所以每一个android上的java进程实际上就是一个linux进程,只是进程中多了一个dalvik虚拟机实例

      操作系统对进程的内存是有限制的,而且操作系统对dalvik虚拟机自身的堆内存大小也是有限制的。可以通过如下命令查看限制大小:

adb shell getprop | grep dalvik.vm.heapgrowthlimit

       堆大小其实是包涵两部分的,一是java的堆,而是native的堆,java堆中主要是一下java对象,由 C/C++申请的内存空间则在native堆中,也有一些对象需要结合native和java堆共同完成

 内存优化如何实现?

 方向:   1 防止内存泄漏2 防止内存溢出

具体措施:

       3.1 字符串优化:当你要频繁操作一个字符串时。使用StringBuffer代替String。减少临时对象的创建就能减少垃圾收集,
进而减少对用户体验的影响。
      3.2 UI视图优化: 减少视图层级,可以有效的减少内存的消耗,因为视图是一个树形结构,每次刷新和渲染都会遍历一次
 ViewStub标签可以使UI在特殊情况下,只管效果类似于设置View的不可见性,但是其最大意义在于被整各标签所包裹的Views在默认状态下不会占用任何内存空间。 3.2.2 include 可以通过这个标签直接加载外部的xml到当前结构中,是复用UI资源的常用标签;
     3.3 尽量使用RecyclerView 来代替ListView 因为强制使用ConvertView,提高复用率;
     3.4 资源方面的使用与回收:3.4.1 避免长期保持某些资源,如Context,Cursor,IO流的引用;
     3.4.2:避免 保存了多个好用内存过大的对象(如Bitmap,xml文件)3.4.3 避免 在查询数据库后没有关闭cursor
     3.4.4 避免使用Bitmap时没有调用recycle()释放内存 3.4.5 避免在使用如广播时,注册后,忘记去取消注册;

 

本文地址:https://blog.csdn.net/ljt2724960661/article/details/107889438