app开发过程中内存泄漏一些简述_懂了这些你的app还在闪退么?

时间:2021-08-18 16:21:54

第一次写blog作为一个小菜的我还是略显压力,希望各位前辈多多提提建议.下面我们就开门见山了,作为一枚屌丝程序猿我表示在开发路上最痛苦的事情莫过内存问题了,什么点着点着越来越卡,什么点着点着直接挂掉….等等一些.那么遇到这些事情后我们该怎么做呢?两字是必不可少的”加班…”,苦逼的我也是这样被逼过来的…人说一入IT深似海呀,果然………


实际上来说,内存优化已经有各种大神提出了好的方案,比如腾讯的凯哥…等等,当然我现在提出来这个东西嘛,大家还是要慎用,毕竟有点小流氓,但可以作为一个备选方案来保证你app不会出现闪退的问题.其实主要的依据..优化Dalvik虚拟机的堆内存分配
对于Android平台来说,其托管层使用的Dalvik Java VM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体原理我们可以参考开源工程,这里我们仅说下使用方法:


   private final static float TARGET_HEAP_UTILIZATION =0.75f; 

在程序onCreate时就可以调用VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);`即可。

Android堆内存也可自己定义大小


对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了
优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的堆内存大小,我们使用Dalvik提供的
dalvik.system.VMRuntime类来设置最小堆内存为例:private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ; VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); 为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理…依据
http://my.oschina.net/u/1244156/blog/167426

其实上述的方法在3.0以后都是行不通的,因为在3.0之后google已经发现这东西太无耻了..所以大家懂的..
咯,显然这货不管你传啥就是0…好傻逼对不对,就跟viewpager你不想预加载一样….就是要给你强制给你改掉…那么面对如此严峻的问题,我们该怎么做呢.经我苦逼寻访各路大神,以及个论坛还是有偶所得滴……..那么下面给大家看看我这个实现….

  ``` /** * 設置系統堆內存大小 * * @param size * @param cwjHeapSize */
   private void setMinHeapSize(long size, float cwjHeapSize) {
       try {
           Class<?> cls = Class.forName("dalvik.system.VMRuntime");
           Method getRuntime = cls.getMethod("getRuntime");
           Object obj = getRuntime.invoke(null);
           if (obj == null) {
               LogUtils.e("obj is null");
           } else {
               LogUtils.e(obj.getClass().getName() + "receive this method");
               Class<?> runtimeClass = obj.getClass();
               Method clearGrowthLimit = runtimeClass.getMethod(
                       "clearGrowthLimit", null);
               Method setTargetHeapUtilization = runtimeClass.getMethod(
                       "setTargetHeapUtilization", float.class);
               LogUtils.e(DataUtils.data2FileSize(size) + "get size");
               if (clearGrowthLimit == null) {
                   LogUtils.d("clearGrowthLimit==" + clearGrowthLimit);
               } else {
                   LogUtils.d("clearGrowthLimit==" + clearGrowthLimit);
                   clearGrowthLimit.invoke(obj);
               }
               setTargetHeapUtilization.invoke(obj, cwjHeapSize);
           }

       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       } catch (NoSuchMethodException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       } } ```

当然,由于我大google开源所以下附上VMRuntime部分的源码,以供大家参考..

 ``` Removes any growth limits, allowing the application to allocate
   up to the maximum heap size.

          clearGrowthLimit(); Sets the current ideal heap utilization, represented as a number between zero and one. After a GC happens, the
   Dalvik heap may be resized so that (size of live objects) / (size of
   heap) is equal to this number.

   This is only a hint to the garbage collector and may be ignored.
   Parameters:

   newTarget the new suggested ideal heap utilization. This value may be
   adjusted internally.

   Returns:

   the previous ideal heap utilization

   Throws:

   java.lang.IllegalArgumentException if newTarget is <= 0.0 or >= 1.0

   111

   112
       public float setTargetHeapUtilization(float newTarget) {[object Object] 113
           if (newTarget <= 0.0 || newTarget >= 1.0) {[object Object] 114
               throw new IllegalArgumentException(newTarget + 115
                       " out of range (0,1)");[object Object] 116
           }[object Object] 117
           /* Synchronize to make sure that only one thread gets[object Object] 118
            * a given "old" value if both update at the same time.[object Object] 119
            * Allows for reliable save-and-restore semantics.[object Object] 120
            */[object Object] 121
           synchronized (this) {[object Object] 122
               float oldTarget = getTargetHeapUtilization();[object Object] 123
               nativeSetTargetHeapUtilization(newTarget);[object Object] 124
 return oldTarget;[object Object] 125
           }
       } ```

以上说明可以帮助大家更好看清楚到底是怎么回事,其实本身我们只要反射到

 ![这里写图片描述](https://img-blog.csdn.net/20151229154525325)clearGrowthLimit 

这个方法我们就可以将app占用内存推到最大同时可以增大系统Gc的频率,使得你的app可以随时保持相对的优秀运行状态.

当然我建议大家要同时使用上面的方法,因为我们的运行内存包括了C和java两个层面,当java虚拟机占用的内存额度较大时候可能导致你的C层出现问题,同时也会出现OOM,所以一般的情况我建议还是将其设置为0.75f的位置是合理的.

 setTargetHeapUtilization 

最后提醒大家的就是app内存优化上面只是临时的解决之策,仅供一些棘手的问题,那么我们在实际开发中就要主要相对应的些对象及时释放,线程池用完关闭,以及使用static的holder….等等相关的一些操作,这样才能真正的解决问题的根源.

以上希望大家多提建议,如有不当请指出,方便大家相互学习.

相关的引用地址供大家参考:

http://my.oschina.net/u/1244156/blog/167426

http://www.cnblogs.com/wanqieddy/archive/2012/07/18/2597471.html

http://grepcode.com/file/repo1.maven.org/maven2/org.robovm/robovm-rt/0.0.11/dalvik/system/VMRuntime.java#VMRuntime.setTargetHeapUtilization%28float%29

http://grepcode.com/file/repo1.maven.org/maven2/org.robovm/robovm-rt/0.0.11/dalvik/system/VMRuntime.java#VMRuntime.nativeSetTargetHeapUtilization%28float%29