精华内容
下载资源
问答
  • 本文大家分享了jQuery内存泄露解决办法,供大家参考,具体内容如下 思路:为JQuery扩展删除jquery元素对象的方法,大大减轻内存泄露的压力 ;(function($){ if(!$.lui.widget) $.lui.widget = {}; //$.lui.newGuid...
  • 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。 1、内存泄露的原因 对于 python 这种支持垃圾回收的语言来说,怎么还会有内存泄露? 概括来说,有以下三...
  • 主要介绍了Android webview 内存泄露解决方法的相关资料,需要的朋友可以参考下
  • 主要介绍了JS常见内存泄漏解决方案解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Android mvp简单模型搭建及其防内存泄漏解决办法
  • 详细说明了QT检测内存泄漏的方法,包括检测工具及其安装方法和设置方法。
  • 内存泄露的危害就是会使虚拟机占用内存过高,导致OOM(内存溢出),程序出错。接下来通过本文给大家分享Android使用Handler造成内存泄露问题及解决方法,一起看看吧
  • 本文通过举例,由浅入深的讲解了解决js函数闭包内存泄露问题的办法,分享给大家供大家参考,具体内容如下 原始代码: function Cars(){ this.name = "Benz"; this.color = ["white","black"]; } Cars.prototype....
  • 内存泄漏的问题,也将是一件非常麻烦的事情了,而最近的一次代码中也碰到了这个问题,不过好在最后内存溢出不是我代码的问题,而是所用到的一个包出现了内存的问题,下面我通过一个简单的代码模拟出内存的问题,然后...
  • 主要介绍了IOS 常见内存泄漏以及解决方案的相关资料,需要的朋友可以参考下
  • webview内存泄漏解决方案

    千次阅读 2020-09-29 13:38:01
    2.引入leakcanary内存泄漏分析工具 由于只运行debug模式来检测,所以只需在build.gradle中引入: debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1' 然后在自定义的Application的O

    1.运行app,先用AS自带的Profiler分析我们的WebViewActivity,频繁进出,看内存占用情况,会发现内存在不断的上升,而且退出当前页面内存只是下降一点,一直持续下去,肯定会OOM;
    2.引入leakcanary内存泄漏分析工具
    由于只运行debug模式来检测,所以只需在build.gradle中引入:

    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'

    然后在自定义的Application的OnCreate方法中加入如下:

    if (LeakCanary.isInAnalyzerProcess(this)) {
                return;
       }
    LeakCanary.install(this);

    接下来重新编译运行APP,继续频繁进出WebviewActivity,LeakCanary会很快检测出内存泄漏风险,等待通知栏下载hprof文件成功,然后点击Android Studio 页面右下角'Device File Explorer',会显示当前手机的文件夹,
     找到"sdcard--->Download--->leakcanary-com.xxx.xxx(后缀是自己包名的文件夹)--->2020-09-29_10-06-28_940.hprof",找到这个文件保存在电脑本地,然后使用工具分析,这里分析的的方式有很多种:
     1.直接使用AS打开,会自动fetch然后可以查看各变量类型使用情况;
     2.使用Eclipse的Eclipse Memory Analyzer;
     3.使用在线分析工具:https://heaphero.io/heap-index.jsp#header(个人比较喜欢使用这个);
     接下来直接按照第三个方式来举例了:
     这是分析的整体结果图:

    然后查看Large objects,会发现webview和drawable占用内存较高,一步步点进去 会发现是Bitmap的buffer导致的内存泄漏风险

     

    那么再回想一下WebViewActivity的布局原来有一张无网的背景图在WebViewActivity频繁进出时没有及时回收导致的(Android5.1和Android8.0检测结果还有差异)。那就开始优化之路--及时回收ImageView组件和Bitmap: 

    // ivNoNetwork是无网的ImageView组件
    	if(ivNoNetwork!= null ){
    		Drawable drawable = ivNoNetwork.getDrawable();
    		if (drawable != null && drawable instanceof BitmapDrawable) {
    			BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    			Bitmap bitmap = bitmapDrawable.getBitmap();
    			if (bitmap != null && !bitmap.isRecycled()) { // 如果还没被回收,才去回收
    				bitmap.recycle();
    			}
    		}
    	}
    	
    	// 同时在父布局中移除这个ImageView, llNoNetwork是ImageView组件的父布局 
    	if(llNoNetwork != null){
    	  llNoNetwork.removeView(ivNoNetwork);  //必须是直接remove它,如果使用removeAllView方法,当很快速度频繁进出时,效率太慢  还是会报leak
    	}
    	ivNoNetwork = null;

    然后重新运行再检测,就不会再报内存泄漏风险了。

    再说一下Webview的常规优化方案:
    1.使用动态添加Webview的方式

    // 动态添加Webview
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT);
            WeakReference weakReference = new WeakReference(this); //使用弱引用去持有当前Activity
            X5WebView webView = new X5WebView((Context) weakReference.get(),null);
            webView.setLayoutParams(params);
            llwebLayout.addView(webView);	

    2.注册的服务、监听器、handler要及时移除并置为null

    3.如果当前页面有ImageView,也要及时回收、销毁

    4.最后再执行super.onDestroy()方法  

    @Override
        protected void onDestroy() {
            try{
                if(mMyRevicer != null){
                    unregisterReceiver(mMyRevicer);
                    mMyRevicer = null;
                }
    
                if(llwebLayout != null){
                    llwebLayout.removeAllViews();
                }
    			
    			// webView清除缓存并销毁
                if (webView != null) {
                    webView.stopLoading();
                    webView.clearHistory();
                    webView.removeAllViewsInLayout();
                    webView.removeAllViews();
                    webView.setWebViewClient(null);
                    webView.destroy();
                    webView = null;
                }
    
    			// 那张无网背景大图,主动回收
                if (ivNoNetwork != null) {
                    Drawable drawable = ivNoNetwork.getDrawable();
                    if (drawable != null && drawable instanceof BitmapDrawable) {
                        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
                        Bitmap bitmap = bitmapDrawable.getBitmap();
                        if (bitmap != null && !bitmap.isRecycled()) {
                            bitmap.recycle();
                        }
                    }
                }
    			
                if (llNoNetwork != null) {
                    llNoNetwork.removeView(ivNoNetwork);   //ImageView的父组件必须是直接remove当前ImageView
                }
                ivNoNetwork = null;
                llNoNetwork = null;
                llwebLayout = null;
                mClickListener= null;
            }catch (Throwable throwable){
                throwable.printStackTrace();
            } finally {
                super.onDestroy();
            }
        }

    如果你使用的是腾讯的X5Webview,在Activity的onDestory方法中最好不要使用这个方法,源码中可以查看到它会new一个新的webview,虽然方法结尾会置空为null

      //官方文档介绍这个API是:一次性删除所有缓存
     // QbSdk.clearAllWebViewCache(this,true);  

    这个是X5Webview SDK的源码:(基于implementation 'com.tencent.tbs.tbssdk:sdk:43939')

    public static void clearAllWebViewCache(Context var0, boolean var1) {
            TbsLog.i("QbSdk", "clearAllWebViewCache(" + var0 + ", " + var1 + ")");
            boolean var2 = false;
    
            WebView var3;
            try {
                var3 = new WebView(var0);
                if (var3.getWebViewClientExtension() != null) {
                    var2 = true;
                    u var4 = com.tencent.smtt.sdk.u.a();
                    if (null != var4 && var4.b()) {
                        var4.c().a(var0, var1);
                    }
                }
    
                var3 = null;
            } catch (Throwable var6) {
                TbsLog.e("QbSdk", "clearAllWebViewCache exception 2 -- " + Log.getStackTraceString(var6));
            }
    
            ...
        }

            以上即是本人解决Webview 内存泄漏的一些个人心得,希望对你有所帮助~

    展开全文
  • RxJava在Android中内存泄漏解决以及RxJava的封装 原文:http://blog.csdn.net/adzcsx2/article/details/51333890 原作者的demo运行有点问题,本人修复重新上传。
  • LINUX内存泄漏解决方法问题排查 内存泄漏问题排查 1、获取内存泄漏程序的进程号 ps -ef | grep java 2、查看该进程下内存对象类全名中包含bshms的对象个数 jmap -histo 进程号 | grep bshms 3、打开java控制台(命令...

    LINUX内存泄漏解决方法问题排查

    内存泄漏问题排查
    1、获取内存泄漏程序的进程号
    ps -ef | grep java
    2、查看该进程下内存对象类全名中包含bshms的对象个数
    jmap -histo 进程号 | grep bshms
    3、打开java控制台(命令jconsole),连接到该进程,切到“内存”tab页,点击右上角的“执行GC”按钮进行垃圾回收,
    4、重复步骤2,看下对象个数,一直增加不减少,和程序内部逻辑不一样的,就是内存泄漏的。

    结合sort命令,来查看:一个JVM中什么类的实例最多?一个JVM中什么类的占用的合计容量最大?
    Q:统计实例最多的类 前十位有哪些?
    A:jmap -histo pid | sort -n -r -k 2 | head -10
    Q:统计合计容量前十的类有哪些?
    A:jmap -histo pid | sort -n -r -k 3 | head 10

    说明:
    sort命令的部分参数含义解释如下
    -n :使用“”纯数字”进行排序(默认是以文字类型来排序)
    -r : 反向排序
    -k :以那个区间(field)来进行排序的意思
    Alt

    展开全文
  • 主要介绍了一次 Java 内存泄漏的排查过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要介绍了Java中典型的内存泄露问题和解决方法,典型的内存泄露例子是一个没有实现hasCode和equals方法的Key类在HashMap中保存的情况,可以通过实现Key类的equals和hasCode方法解决这种内存泄漏问题,需要的朋友可以...
  • 导读:C++内存泄漏问题的分析、定位一直是Android平台上困扰开发人员的难题。因为地图渲染、导航等核心功能对性能要求很高,高德地图APP中存在大量的C++代码。解决这个问题对于产品质量尤为重要和关键,高德地图技术...
  • 在android开发过程中,我们可能会遇到过令人奔溃的OOM异常,这篇文章主要介绍了Android Handler内存泄漏详解及其解决方案,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 今天小编就为大家分享一篇解决Tensorflow 内存泄露问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 故事背景 很早之前用表弟的学生证薅了一个...fatal error: runtime: out of memory很明显服务器内存泄漏,撑爆了。 解决方式 排查原因发现是由于一个 gitlab 进程导致,杀掉 gitlab 相关进程服务正常使用但是发现在浏

    故事背景

    很早之前用表弟的学生证薅了一个阿里云低配的主机,前段时间快到期也一只没续费等到过期啦才想起来要续费,还好赶在服务器数据清除之前续费成功,但当我登录到服务器中发现有点卡不流畅这是什么情况,而且发现服务器中 docker 无法运行.

    事件排查

    当在服务器运行 docker 时会抱如下错误:
    在这里插入图片描述
    fatal error: runtime: out of memory很明显服务器内存泄漏,撑爆了。

    解决方式

    排查原因发现是由于一个 gitlab 进程导致,杀掉 gitlab 相关进程服务正常使用但是发现在浏览器中还是无法正常访问到服务器的服务,但是服务地址(网址)可以正常 ping 通,使用 netstat -anp | grep :80 发现 nginx 没起。

    • 使用 nginx -s reload 报错如下
    # nginx -s quit
    nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)
    
    • 解决方式
    # 使用如下命令:
    /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf (使用nginx -c的参数指定nginx.conf文件的位置)
    
    # 再次重启 ngin 服务正常启动,服务器中的服务也可正常访问
    nginx -s reload
    
    展开全文
  • 主要介绍了PHP CURL 内存泄露问题解决方法,CRUL长时间访问HTTPS网站时有内存泄露问题,本文经过反复调试找到了解决方法,需要的朋友可以参考下
  • 主要介绍了Java 分析并解决内存泄漏的实例,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
  • Vue-Cli内存泄露部分原因 1、echarts图未彻底删除; 2、setTimeout和setInterval未清除; 3、全局定于变量未清除; 4、侦听器未清除 场景分析 其中全局对象onresize,侦听事件应在组价销毁前清除。 重点:在vue中...
  • 一、Map 1.定义 Map对象保存键值对,类似于数据结构字典;与传统上的对象只能用字符串当键不同,Map对象可以使用任意值当键。 2.语法 new Map([iterable]) 属性 size:返回键值对的数量。... set(key, value):设置...
  • 常见的内存泄漏原因及解决方法

    万次阅读 2019-02-22 04:54:14
    (Memory Leak,内存泄漏) 为什么会产生内存泄漏? 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这...

    (Memory Leak,内存泄漏)

    为什么会产生内存泄漏?

    当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏。

    内存泄漏对程序的影响?

    内存泄漏是造成应用程序OOM的主要原因之一。我们知道Android系统为每个应用程序分配的内存是有限的,而当一个应用中产生的内存泄漏比较多时,这就难免会导致应用所需要的内存超过系统分配的内存限额,这就造成了内存溢出从而导致应用Crash。

    如何检查和分析内存泄漏?

    因为内存泄漏是在堆内存中,所以对我们来说并不是可见的。通常我们可以借助MAT、LeakCanary等工具来检测应用程序是否存在内存泄漏。
    1、MAT是一款强大的内存分析工具,功能繁多而复杂。
    2、LeakCanary则是由Square开源的一款轻量级的第三方内存泄漏检测工具,当检测到程序中产生内存泄漏时,它将以最直观的方式告诉我们哪里产生了内存泄漏和导致谁泄漏了而不能被回收。

    常见的内存泄漏及解决方法

    1、单例造成的内存泄漏

    由于单例的静态特性使得其生命周期和应用的生命周期一样长,如果一个对象已经不再需要使用了,而单例对象还持有该对象的引用,就会使得该对象不能被正常回收,从而导致了内存泄漏。
    示例:防止单例导致内存泄漏的实例

    // 使用了单例模式
    public class AppManager {
        private static AppManager instance;
        private Context context;
        private AppManager(Context context) {
            this.context = context;
        }
        public static AppManager getInstance(Context context) {
            if (instance != null) {
                instance = new AppManager(context);
            }
            return instance;
        }
    }
    

    这样不管传入什么Context最终将使用Application的Context,而单例的生命周期和应用的一样长,这样就防止了内存泄漏。???

    2、非静态内部类创建静态实例造成的内存泄漏

    例如,有时候我们可能会在启动频繁的Activity中,为了避免重复创建相同的数据资源,可能会出现如下写法:

    public class MainActivity extends AppCompatActivity {
    
        private static TestResource mResource = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if(mResource == null){
                mResource = new TestResource();
            }
            //...
        }
        
        class TestResource {
        //...
        }
    }
    

    这样在Activity内部创建了一个非静态内部类的单例,每次启动Activity时都会使用该单例的数据。虽然这样避免了资源的重复创建,但是这种写法却会造成内存泄漏。因为非静态内部类默认会持有外部类的引用,而该非静态内部类又创建了一个静态的实例,该实例的生命周期和应用的一样长,这就导致了该静态实例一直会持有该Activity的引用,从而导致Activity的内存资源不能被正常回收。
    解决方法:将该内部类设为静态内部类或将该内部类抽取出来封装成一个单例,如果需要使用Context,就使用Application的Context。

    3、Handler造成的内存泄漏

    示例:创建匿名内部类的静态对象

    public class MainActivity extends AppCompatActivity {
    
        private final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // ...
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // ...
                    handler.sendEmptyMessage(0x123);
                }
            });
        }
    }
    

    1、从Android的角度
    当Android应用程序启动时,该应用程序的主线程会自动创建一个Looper对象和与之关联的MessageQueue。当主线程中实例化一个Handler对象后,它就会自动与主线程Looper的MessageQueue关联起来。所有发送到MessageQueue的Messag都会持有Handler的引用,所以Looper会据此回调Handle的handleMessage()方法来处理消息。只要MessageQueue中有未处理的Message,Looper就会不断的从中取出并交给Handler处理。另外,主线程的Looper对象会伴随该应用程序的整个生命周期。
    2、 Java角度
    在Java中,非静态内部类和匿名类内部类都会潜在持有它们所属的外部类的引用,但是静态内部类却不会。

    对上述的示例进行分析,当MainActivity结束时,未处理的消息持有handler的引用,而handler又持有它所属的外部类也就是MainActivity的引用。这条引用关系会一直保持直到消息得到处理,这样阻止了MainActivity被垃圾回收器回收,从而造成了内存泄漏。
    解决方法:将Handler类独立出来或者使用静态内部类,这样便可以避免内存泄漏。

    4、线程造成的内存泄漏

    示例:AsyncTask和Runnable

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            new Thread(new MyRunnable()).start();
            new MyAsyncTask(this).execute();
        }
    
        class MyAsyncTask extends AsyncTask<Void, Void, Void> {
    
            // ...
    
            public MyAsyncTask(Context context) {
                // ...
            }
    
            @Override
            protected Void doInBackground(Void... params) {
                // ...
                return null;
            }
    
            @Override
            protected void onPostExecute(Void aVoid) {
                // ...
            }
        }
    
        class MyRunnable implements Runnable {
            @Override
            public void run() {
                // ...
            }
        }
    }
    

    AsyncTask和Runnable都使用了匿名内部类,那么它们将持有其所在Activity的隐式引用。如果任务在Activity销毁之前还未完成,那么将导致Activity的内存资源无法被回收,从而造成内存泄漏。
    解决方法:将AsyncTask和Runnable类独立出来或者使用静态内部类,这样便可以避免内存泄漏。

    5、资源未关闭造成的内存泄漏

    对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,从而造成内存泄漏。

    1)比如在Activity中register了一个BraodcastReceiver,但在Activity结束后没有unregister该BraodcastReceiver。
    2)资源性对象比如Cursor,Stream、File文件等往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存。它们的缓冲不仅存在于 java虚拟机内,还存在于java虚拟机外。如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄漏。
    3)对于资源性对象在不使用的时候,应该调用它的close()函数将其关闭掉,然后再设置为null。在我们的程序退出时一定要确保我们的资源性对象已经关闭。
    4)Bitmap对象不在使用时调用recycle()释放内存。2.3以后的bitmap应该是不需要手动recycle了,内存已经在java层了。

    6、使用ListView时造成的内存泄漏

    初始时ListView会从BaseAdapter中根据当前的屏幕布局实例化一定数量的View对象,同时ListView会将这些View对象缓存起来。当向上滚动ListView时,原先位于最上面的Item的View对象会被回收,然后被用来构造新出现在下面的Item。这个构造过程就是由getView()方法完成的,getView()的第二个形参convertView就是被缓存起来的Item的View对象(初始化时缓存中没有View对象则convertView是null)。

    构造Adapter时,没有使用缓存的convertView。
    解决方法:在构造Adapter时,使用缓存的convertView。

    7、集合容器中的内存泄露

    我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就更严重了。
    解决方法:在退出程序之前,将集合里的东西clear,然后置为null,再退出程序。

    8、WebView造成的泄露

    当我们不要使用WebView对象时,应该调用它的destory()函数来销毁它,并释放其占用的内存,否则其长期占用的内存也不能被回收,从而造成内存泄露。
    解决方法:为WebView另外开启一个进程,通过AIDL与主线程进行通信,WebView所在的进程可以根据业务的需要选择合适的时机进行销毁,从而达到内存的完整释放。

    如何避免内存泄漏?

    1、在涉及使用Context时,对于生命周期比Activity长的对象应该使用Application的Context。凡是使用Context优先考虑Application的Context,当然它并不是万能的,对于有些地方则必须使用Activity的Context。对于Application,Service,Activity三者的Context的应用场景如下:

     

     

    其中,NO1表示Application和Service可以启动一个Activity,不过需要创建一个新的task任务队列。而对于Dialog而言,只有在Activity中才能创建。除此之外三者都可以使用。

    2、对于需要在静态内部类中使用非静态外部成员变量(如:Context、View ),可以在静态内部类中使用弱引用来引用外部类的变量来避免内存泄漏。
    3、对于不再需要使用的对象,显示的将其赋值为null,比如使用完Bitmap后先调用recycle(),再赋为null。
    4、保持对对象生命周期的敏感,特别注意单例、静态对象、全局性集合等的生命周期。
    5、对于生命周期比Activity长的内部类对象,并且内部类中使用了外部类的成员变量,可以这样做避免内存泄漏:
    1)将内部类改为静态内部类
    2)静态内部类中使用弱引用来引用外部类的成员变量

    参考

    Android内存泄漏总结



    作者:李俊的博客
    链接:https://www.jianshu.com/p/90caf813682d
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    展开全文
  • vue的自定义指令是一个比较容易引起内存泄漏的地方,原因就在于指令通常给元素绑定了事件,但是如果忘记了解绑,就会产生内存泄漏的问题。 看下面代码: directives: { scroll: { inserted (el, cb) { // 不是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 194,802
精华内容 77,920
关键字:

内存泄露解决