精华内容
下载资源
问答
  • 服务器中polkits内存占用很大,经过查阅资料发现可能...polkits存在内存泄漏现象。​ 参考: Bug29069-polkitd memory leaks https://bugs.freedesktop.org/show_bug.cgi?id=29069 进一步发现在redhat的bug清...
    服务器中polkits内存占用很大,经过查阅资料发现可能是polkits的内存泄漏导致,这个可以作为后续服务器内存分析的一个参考。
     
    polkits存在内存泄漏现象。​
    参考:
    Bug 29069 - polkitd memory leaks
     
    进一步发现在redhat的bug清单中存在该内存泄漏bug。
    参考:
    Bug 1380166 - polkitd keeps consuming RAM
     
    并且在2017-05-05对这个bug进行了修复,并且提供了相应的修复软件包。
    参考:
    RHBA-2017:1306 - Bug Fix Advisory
    展开全文
  • 什么是内存泄漏 指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。 造成这种现象的原因要从,jvm内存模型和java GC机制说起 一般局部变量是存在java...

    什么是内存泄漏

    指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。

    造成这种现象的原因要从,jvm内存模型和java GC机制说起
    在这里插入图片描述
    一般局部变量是存在java虚拟机栈的栈帧里,在代码里一个方法就会有一个栈帧, new一个对象他会在堆里开辟块内存来存放他的实例,当这个实例赋值给局部变量的时候,就把它们通过动态链接连接上了,这就是常说的栈指向堆。

    当方法执行完成后,栈帧就弹出java虚拟机栈,然后销毁,但之前动态链接指向的对象实例任然会存在在堆内存里。这时就有javaGC的机制来处理这已经不用的对象了。

    结构

    这时说一下堆内存的结构,堆是由新生代和老年代组成,新生代里又有Eden和SurvivorFrom、SurvivorTo区。

    垃圾判断算法

    一般通过这两种算法去判断对象是否存活:1.引用计数法 2.可达性分析算法

    分代收集算法

    分代收集算法分代收集算法严格来说并不是一种思想或理论,而是融合上述3种基础的算法思想,而产生的针对不同情况所采用不同算法的一套组合拳,根据对象存活周期的不同将内存划分为几块。

    新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

    老年代中,因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记-清理算法或者标记-整理算法来进行回收。

    对象年龄

    虚拟机给每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中(正常情况下对象会不断的在Survivor的From与To区之间移动),并且对象年龄设为1。对象在Survivor区中每经历一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认15岁),就将会晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数 XX:MaxPretenuringThreshold 设置。

    GC流程

    Minor GC
    新new对象的时候会在Eden区开辟内存空间,当Eden区没有足够空间进行分配时,虚拟机会发起一次 Minor GC,此时就会把Eden+SurvivorFrom里面没有非存活的对象都回收调,把存活的对象用复制回收算法放到SurvivorTo区里面(如果From内存不足了,会直接放到老年代里),然后From Survivor和To Survivor的逻辑关系会发生颠倒: From变To , To变From,目的是保证有连续的空间存放对方,避免碎片化的发生。这样第二次Minor GC的时候就会把Eden区存活的对象放到了之前的SurvivorTo里了。

    Full GC
    每一次Minor GC过后,都会往新生代里的Survivor区放还存活的对象,而本身就存在在Survivor区存活的对象则会年龄+1,直到到达年龄最大限制值时(可以通过配置XX:MaxPretenuringThreshold来修改最大年龄限制,此参数默认为15),会通过复制回收算法把对象放到老年代里。当很多次这样的操作之后,老年代内存也写满了,就会触发Full GC了。

    内存泄漏现象详细描述

    内存泄漏现象就是,在开发时,创建完一个对象之后,这个对象在后面的代码里没有再需要用他了,但是却还被之前代码引用着无法释放,他就会先一直存放在新生代的Survivor区里,直达多次Minor GC 让这对象的年龄到达设置的最高值,最终到老年代里,而老年代里的对象是只有老年代写满后触发的Full GC才能回收资源,所以他就一直站着内存不释放,而且程序里也没有再使用他的地方,这样就是内存泄漏。

    内存泄漏处理

    三个方面处理
    1.主要因为代码原因造成的内存泄漏,可以找机器内存里占内存比较多的类,找到用他的方法,优化代码逻辑,及时释放对象的引用。
    2.jvm参数,可以通过增大XX:MaxPretenuringThreshold参数值,让对象更有可能被Minor GC回收掉,但同时得用XX:PretenureSizeThreshold这个参数限制存放在新生代的最大的对象是多少,防止对象在新生区,占用空间大,会由于空间不足而导致很多小对象进入到老年区,最后可以增大Survivor区的内存使用率-XX:TargetSurvivorRatio这个参数(默认为50%),降低进入老年代的频率。
    3.机器根据程序的访问量来保证数量,还得做好负载均衡,防止某一台机器访问量过高,这样也容易造成内存泄漏,当内存泄漏严重的时候,会造成内存溢出,从服务挂掉。

    展开全文
  • 当遇到这个输入法造成的内存泄露的时候,我表示一脸惊讶,因为我整个Activity中没有如何一个输入类控件,更不存在使用输入键盘。但是内存就这样不知不觉的泄露了。既然遇到了问题,我们就要寻求解决方案。 先看一下...

    当遇到这个输入法造成的内存泄露的时候,我表示一脸惊讶,因为我整个Activity中没有如何一个输入类控件,更不存在使用输入键盘。但是内存就这样不知不觉的泄露了。既然遇到了问题,我们就要寻求解决方案。
    先看一下内存泄露对象InputMethodManager的引用路径
    这里写图片描述

    要想让Activity释放掉,思路就是将path togc这个链路剪断就可以.在这个bug中这个链路上有两个节点mContext(DecorView)和 mCurRootView(InputMethodManager)可供考虑.下面思路就是从这两个节点中选择一个入手剪断path to gc即可.

    阅读源码可知, DecorView继承自FrameLayout,mContext是其上下文环境,牵涉太多,不适合操作入手.mCurRootView在InputMehtodManager中的使用就简单得多了,在被赋值初始化后,被使用的场景只有一次判断及一次日志打印.所以这里选中mCurRootView为突破口.剪断其path to gc的操作为通过Java Reflection方法将mCurRootView置空即可(见文后代码).

    编码实现后,再测,发现仍有泄露,但泄露情况有所变化,如下图:
    这里写图片描述

    新的泄露点为mServedView/mNextServedView,可以通过同样的JavaReflection将其置空,剪断path to gc.但这里有个问题得小心,这里强制置空后,会不会引起InputMethodManager的NullPointerException呢?会不会引起系统内部逻辑崩溃?再次查阅源码,发现mServedView及mNextServedView在代码逻辑中一直有判空逻辑,所以这时就可以放心的强制置空来解决问题了.
    这里写图片描述

    为了让输入法在特定的Activity中置空,在其他的Activity中显示,我们需要做判断。fixInputMethodManagerLeak(ContextdestContext)方法参数中将目标要销毁的Activity A作为参数传参进去。在代码中,去获取InputMethodManager的关联View,通过View.getContext()与Activity A进行对比,如果发现两者相同,就表示需要回收;如果两者不一样,则表示有新的界面已经在使用InputMethodManager了,直接不处理就可以了。

    下面写一个InputMethodManager工具类来处理内存泄露,下面直接贴代码:

    package com.hwapu.education.teacher.utils;
    
    import java.lang.reflect.Field;
    
    import android.content.Context;
    import android.view.View;
    import android.view.inputmethod.InputMethodManager;
    
    /**
     * @author tangdekun
     * 用于输入法管理
     */
    public class InputMethodManagerUtils {
    
    
    
    
        /**
         * @param destContext 上下文对象
         * 用于解决输入法内存泄露
         * 参考:http://blog.csdn.net/sodino/article/details/32188809
         */
        public static void fixInputMethodManagerLeak(Context destContext) {  
            if (destContext == null) {  
                return;  
            }  
    
            InputMethodManager imm = (InputMethodManager) destContext.getSystemService(Context.INPUT_METHOD_SERVICE);  
            if (imm == null) {  
                return;  
            }  
    
            String [] arr = new String[]{"mCurRootView", "mServedView", "mNextServedView"};  
            Field f = null;  
            Object obj_get = null;  
            for (int i = 0;i < arr.length;i ++) {  
                String param = arr[i];  
                try{  
                    f = imm.getClass().getDeclaredField(param);  
                    if (f.isAccessible() == false) {  
                        f.setAccessible(true);  
                    } // author: sodino mail:sodino@qq.com  
                    obj_get = f.get(imm);  
                    if (obj_get != null && obj_get instanceof View) {  
                        View v_get = (View) obj_get;  
                        if (v_get.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的  
                            f.set(imm, null); // 置空,破坏掉path to gc节点  
                        } else {  
                            // 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了        
                            break;  
                        }  
                    }  
                }catch(Throwable t){  
                    t.printStackTrace();  
                }  
            }  
        }
    
    }
    

    直接在内存泄露的Activity的onDestory()方法中执行该方法:

    @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            InputMethodManagerUtils.fixInputMethodManagerLeak(this);
            super.onDestroy();
    
        }


    参考文章:
    [Android][Memory Leak] InputMethodManager内存泄露现象及解决

    展开全文
  • [Android][Memory Leak]InputMethodManager内存泄露现象及解决 现象:  在特定的机型天语k_touch_v9机型上,某个界面上出现InputMethodManager持有一Activity,导致该Activity无法回收.如果该Activity再次被打开,则旧...

    [Android][Memory Leak] InputMethodManager内存泄露现象及解决

    现象:

             在特定的机型天语k_touch_v9机型上,某个界面上出现InputMethodManager持有一Activity,导致该Activity无法回收.如果该Activity再次被打开,则旧的会释放掉,但新打开的会被继续持有无法释放回收.MAT显示Path to gc如下:

    1. Leak path

             天语k_touch_v9手机版本信息:

    2. K_touch_v9

     

    一番搜索后,已经有人也碰到过这个问题(见文章最后引用链接),给出的方法是:

    @Override
    public void onDestory() {
        //Fix memory leak: http://code.google.com/p/android/issues/detail?id=34731
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.windowDismissed(this.getWindow().getDecorView().getWindowToken()); // hide method
        imm.startGettingWindowFocus(null); // hide method
        super.onDestory();
    }


    但在实践中使用后,没有真正解决,Activity仍存在,path to gc指向为unknown.如下图:

    3. Unknownpath

     

    搜索来的代码不管用,就再想办法.

    要想让Activity释放掉,思路就是将path togc这个链路剪断就可以.在这个bug中这个链路上有两个节点mContext(DecorView) mCurRootView(InputMethodManager)可供考虑.下面思路就是从这两个节点中选择一个入手剪断path to gc即可.

    阅读源码可知, DecorView继承自FrameLayout,mContext是其上下文环境,牵涉太多,不适合操作入手.mCurRootViewInputMehtodManager中的使用就简单得多了,在被赋值初始化后,被使用的场景只有一次判断及一次日志打印.所以这里选中mCurRootView为突破口.剪断其path to gc的操作为通过Java Reflection方法将mCurRootView置空即可(见文后代码).

    编码实现后,再测,发现仍有泄露,但泄露情况有所变化,如下图:

    4. Leak path

             新的泄露点为mServedView/mNextServedView,可以通过同样的JavaReflection将其置空,剪断path to gc.但这里有个问题得小心,这里强制置空后,会不会引起InputMethodManagerNullPointerException?会不会引起系统内部逻辑崩溃?再次查阅源码,发现mServedViewmNextServedView在代码逻辑中一直有判空逻辑,所以这时就可以放心的强制置空来解决问题了.


    5. 判空逻辑

             最后贴出代码实现:

                  public static void fixInputMethodManagerLeak(Context context) {
                                if (context == null) {
                                              return;
                                }
                                try {
                                              // 对 mCurRootView mServedView mNextServedView 进行置空...
                                              InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                                              if (imm == null) {
                                                            return;
                                              }// author:sodino mail:sodino@qq.com
     
                                              Object obj_get = null;
                                              Field f_mCurRootView = imm.getClass().getDeclaredField("mCurRootView");
                                              Field f_mServedView = imm.getClass().getDeclaredField("mServedView");
                                              Field f_mNextServedView = imm.getClass().getDeclaredField("mNextServedView");
     
                                              if (f_mCurRootView.isAccessible() == false) {
                                                            f_mCurRootView.setAccessible(true);
                                              }
                                              obj_get = f_mCurRootView.get(imm);
                                              if (obj_get != null) { // 不为null则置为空
                                                            f_mCurRootView.set(imm, null);
                                              }
     
                                              if (f_mServedView.isAccessible() == false) {
                                                            f_mServedView.setAccessible(true);
                                              }
                                              obj_get = f_mServedView.get(imm);
                                              if (obj_get != null) { // 不为null则置为空
                                                            f_mServedView.set(imm, null);
                                              }
     
                                              if (f_mNextServedView.isAccessible() == false) {
                                                            f_mNextServedView.setAccessible(true);
                                              }
                                              obj_get = f_mNextServedView.get(imm);
                                              if (obj_get != null) { // 不为null则置为空
                                                            f_mNextServedView.set(imm, null);
                                              }
                                } catch (Throwable t) {
                                              t.printStackTrace();
                                }
                  }


             Activity.onDestory()方法中执行以上方法即可解决.

                  public  void onDestroy() {
                                super.ondestroy();
                                fixInputMethodManagerLeak(this);
                  }

     

             事情看上去圆满的解决了,但真的是吗?

             经过以上处理后,内存泄露是不存在了,但出现另外一个问题,就是有输入框的地方,点击输入框后,却无法出现输入法界面了!

             事故现场复现的操作步骤为:

             ActivityA界面,点击进入Activity B界面,B有输入框,点击输入框后,没有输入法弹出。原因是InputMethodManager的关联View已经被上面的那段代码置空了。

             事故原因得从Activity间的生命周期方法调用顺序说起:

             从Activity A进入Activity B的生命周期方法的调用顺序是:

     

    A.onCreate()→A.onResume()→B.onCreate()→B.onResume()→A.onStop()→A.onDestroy()
     

    也就是说,Activity B已经创建并显示了,ActivityA这里执行onDestroy()将InputMethodManager的关联View置空了,导致输入法无法弹出。

    原因发现了,要解决也就简单了。

    fixInputMethodManagerLeak(ContextdestContext)方法参数中将目标要销毁的Activity A作为参数传参进去。在代码中,去获取InputMethodManager的关联View,通过View.getContext()与Activity A进行对比,如果发现两者相同,就表示需要回收;如果两者不一样,则表示有新的界面已经在使用InputMethodManager了,直接不处理就可以了。

    修改后,最终代码如下:

    public static void fixInputMethodManagerLeak(Context destContext) {
    	if (destContext == null) {
    		return;
    	}
    	
    	InputMethodManager imm = (InputMethodManager) destContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    	if (imm == null) {
    		return;
    	}
    
    	String [] arr = new String[]{"mCurRootView", "mServedView", "mNextServedView"};
    	Field f = null;
    	Object obj_get = null;
    	for (int i = 0;i < arr.length;i ++) {
    		String param = arr[i];
    		try{
    			f = imm.getClass().getDeclaredField(param);
    			if (f.isAccessible() == false) {
    				f.setAccessible(true);
    			} // author: sodino mail:sodino@qq.com
    			obj_get = f.get(imm);
    			if (obj_get != null && obj_get instanceof View) {
    				View v_get = (View) obj_get;
    				if (v_get.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
    					f.set(imm, null); // 置空,破坏掉path to gc节点
    				} else {
    					// 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了
    					if (QLog.isColorLevel()) {
    						QLog.d(ReflecterHelper.class.getSimpleName(), QLog.CLR, "fixInputMethodManagerLeak break, context is not suitable, get_context=" + v_get.getContext()+" dest_context=" + destContext);
    					}
    					break;
    				}
    			}
    		}catch(Throwable t){
    			t.printStackTrace();
    		}
    	}
    }


     

    引用:

    l InputMethodManager:googlecode

    l InputMethodManger导致的Activity泄漏

    l MainActivity is not garbage collected after destruction because it is referenced byInputMethodManager indirectly

    l InputMethodManagerholds reference to the tabhost - Memory Leak - OOM Error

     

     

    展开全文
  • 现象: 在特定的机型上,某个界面上出现InputMethodManager持有一Activity,导致该Activity无法回收.如果该Activity再次被打开,则旧的会释放掉,但新打开的会被继续持有无法释放回收. 要想让Activity释放掉,思路就是将...
  • .NET的托管堆中是否可能出现内存泄漏现象本文节选自《.NET程序员面试指南》一书 这一问题的难度比较大,主要注重的是应聘人员的程序开发经验。如果切身经历过一些内存泄漏的情况,那应聘者将比较容易回答此类问题。...
  • 前几天在定位一个很奇怪的"内存泄漏"问题。我们的服务在arm下面跑到好好的,但是在x86下面的环境下面内存运行时间久了就上涨。用vargrind工具检查内存,也没发现什么问题,说明我们的代码方面应该试ok的。 对比一下...
  • 其实java有内存泄漏现象垃圾回收机制只能回收没有引用的对象,也就是说只能回收没有“指针”的对象,对于非引用类对象,垃圾回收机制就不能起作用比如说,如果打开过多的数据库连接,那么这些不能被垃圾回收机制所...
  • 在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要再使用了,本该被...
  • 内存溢出(OutOfMemoryError 简称 OOM异常) ... 设置堆内存为10M后用JVM执行字节码文件, 出现内存溢出现象 java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError com.cloud.jvm.OutOfMemoryErr...
  • 内存泄露解决方法

    2018-09-18 08:27:09
    线上内存泄露现象,面临JVM内存泄漏常用调优方法、GC优化
  • 今天在部署实验室项目时,发现项目在后台运行一个晚上后内存增长了近3g。考虑到目前的数据量较小,真正...在分析内存泄露之前需要先了什么情况会导致内存泄露.具体内容可以参照如下几篇博客:检测内存泄露接下来检测...
  • 通过反射直接置null [Android][Memory Leak] InputMethodManager内存泄露现象及解决 InputMethodManager内存泄漏引发对View加载的探究 跳转一个空的dummy Activity InputMethodManager导致的内存泄漏 ...
  • 虚引用(WeakReference) 在开始之前,需要区分 Java引用中的强、软、弱、虚引用,ThreadLocal 使用了弱引用,它是...ThreadLocal内存模型 每个线程自己保存一个Map,即 ThreadLocalMap,这个 Map以ThreadLocal...
  • 什么是内存泄漏呢?借助别的大佬给出的定义,内存泄漏就是指由于疏忽或者程序的某些错误造成未能释放已经不再使用的内存的情况。简单来讲就是 假设某个变量占用100M的内存,而你又用不到这个变量,但是这个变量没有...
  • js内存泄漏详解

    2017-11-09 10:04:58
    JavaScript常见内存泄漏原因及其解决方式 内存泄漏的定义 本质上来说,即是那些无法被应用所使用但又...在js中,无效的引用代码中本应释放的已经引用的内存却没有释放的变量,就会造成内存泄漏现象 对于内存使用...
  • 内存泄漏总结

    2021-01-26 16:00:23
    什么是内存泄漏:程序在申请内存后,当该内存不需再使用但却无法被释放&归还给程序的现象,对应用程序的影响,容易使得应用程序发生内存溢出,即OOM。 内存泄漏的原因: 1,资源对象没关闭造成的内存泄漏,如...
  • 内存溢出和内存泄露

    2018-08-09 22:58:05
    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory; 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存...发生内存泄漏的代码会被多次执行到,每次...
  • 内存泄漏

    2021-05-07 21:35:06
    内存泄漏现象: 程序刚刚跑起来没有问题,但是过了几小时或者几天,程序崩溃,大概率是内存泄漏造成的。 什么是内存泄漏: malloc函数申请的内存空间,在使用完之后没用free函数释放。系统不能再次访问这片内存...
  • 虽然JAVA有垃圾回收的机制,但是如果不及时释放引用就会发生内存泄露现象。在实际工作中我们使用Jprofiler调用java自带的jmap来做检测还是很快能够定位到错误。不过亡羊补牢不如先把羊圈修补得好一些。下面这篇文章...
  • 浏览器内存泄露

    2016-01-08 10:55:52
    在你的程序运行结束后,无法找到你变量的作用域对象,进而无法清除内存中的变量,这就是内存泄露现象 什么情况会导致浏览器内存泄露 通常来说,以下三种情况可能会导致内存泄露的现象发生: 循环引用自动类型...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,676
精华内容 13,870
关键字:

内存泄漏的现象