面试常客之内存管理

前言:内存管理首先就要了解一下内存的分类,一般分为:物理内存(RAM)、进程内存。

1、android 系统拥有一套内存回收的规则,依次对以下进程进行回收,释放内存:空进程、后台进程、可见进程、服务进程、前台进程由高到低依次回收释放。
2、系统自动回收内存是当到达一定阈(yù)值时。
3、在说一说Java的内存分配垃圾回收机制

作图中由三部分组成:Class Loader(子系统和执行引擎)、运行时方法区和本地方法区,内存管理主要在运行时方法区(RUNTIME DATA AREA)。
    3-1、RUNTIME DATA AREA(运行时方法区)组成:
             @1、method area(方法区):一些被装载的class元信息存储在其中,它线程共享的
             @2、Java  stack(Java 栈):Java虚拟机直接对Java 栈进行两种操作,以帧为单位的压栈和出栈,存放对象引用,它非线程共享的
             @3、native method stack (本地方法栈):非线程共享
             @4、heap(堆):一个Java虚拟机中只有一个,存放对象信息(对象数据),线程共享的
             @5、program counter register(程序计数器):它时非线程共享的
    3-2、jvm的垃圾回收机制(GC):
             @1、组成可分为:年轻代(新生区(eden)、2个幸存区(survivor))、老年代、持久代。
             @2、组成介绍和规则:年轻代新生区存放刚创建的对象,当此区满时,将复制还存活的对象进入第一个幸存区,当此区满时,会复制存活的对象进入第二个幸存区,最后一个也满时,将会复制存活对象进入老年代。持久代里放的是静态的类和方法,一般说对此垃圾回收机制没有显著的影响。
4、如何排查在内存分配和垃圾回收时是否造成内存泄漏呢?DDMS-help可以帮你。
5、内存泄漏(Memory Leak):非合理使用内存或是垃圾对象在不经意间引用到GC-root导致无法回收。
6、内存溢出(OOM):主角为堆(heap),虚拟机堆内存增长上限值大于程序向Java申请的堆内存时。(并非内存不足)

内存优化:
1、对bitmap进行优化,原因:在加载位图图片时,虚拟机分配给bitmap的堆栈内存只有8M,所以会经常造成OOM。
      1-1、图片显示:能小尽力小,能使用缩率图尽量使用
      1-2、图片回收:bitmap使用完后及时回收,Bitmap.recycle()使用。(为什么虚拟机垃圾回收机制不能自动回收?原因:bitmap是由bitmapfacotry制造,而不是我们手动new 出来的。回收机制 回收手动的,系统工厂制造的不可回收。而且源码是通过jni生成bitmap的(nativedecodestream()方法),会造成虚拟机内存上升和linux内核内存上升,前者可自动回收,后者必须由源码提供的回收方法回收。)
      1-3、捕获OOM异常,及时处理。
      1-4、图片缓存,内存缓存和磁盘缓存
      1-5、图片压缩:不可用image view直接显示bitmap,会内存过大,使用bitmapfactory.options对图片进行压缩。
      1-6、图片像素:ARGB_8888,显示质量高,使用内存大。
2、合理使用对象引用类型。
      2-1、强引用:一般不会被回收,即使是OOM
      2-2、软引用(SoftReference):一般用于缓存,达到某个阈值时才会回收
      2-3、弱引用(WeakReference):只要回收机制(GC)扫描到,就会回收
      2-4、虚引用(PhantomReference):一般用于检测对象是否被删除,pf.get();//永远返回null,pf.isEnQueued();//返回是否从内存中已经删除
3、对象池、线程池的合理使用
      3-1、线程池运行机制:池中拥有下限和上限线程个数,默认线程池会创建下限个数的空线程,当有线程任务进入时,会逐一使用已创建好的空线程,当任务数大于下限个数时,系统会等待500ms,如果其中没有已完成的线程时,则会创建新的线程,当总线程都正在使用,且使用个数大于上限个数时,系统则又会等待120ms,同上没有已完成的线程时,超出的任务则会等待原运行的线程,一旦有完成的,就立刻排除原任务,执行新任务。而当任务数递减到上限个数时,上限个数线程则会等待120s,没有新的任务进入时,会逐一被回收,直达下限个数。完成所有任务后,默认会存在下限个数线程。(以下不可使用线程池情况:线程执行时间过长、需要为线程指定单独的优先级、使用线程中需要对线程进项操作的,比如睡眠或挂起。)
      3-2、对象池的使用:创建对象池作为cache,使用时从池中取出,用完后放入池中,减少创建对象的开销。而其中则会使用到concurrentbag,它可对数据,对象进行线程标记,所有使用他来存取对象数据时会很快,如果所取数据此线程不存在时则回去其他的线程取值,为保证线程的安全而损耗部分性能。
      3-3、穿插连接池介绍、此技术为的是解决频繁连接数据库,造成应用性能极差,甚至导致系统崩溃。原理则是将连接数据库作为一个对象存入vector中,共享此链接,减少连接数据库的频繁度。
4、缓存机制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值