精华内容
下载资源
问答
  • 内存泄漏问题\防范JAVA内存泄漏解决方案
  • 一、内存泄漏像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题。对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。1、...

    29.jpg

    一、内存泄漏

    像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题。

    对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。

    1、内存泄露的原因

    对于 python 这种支持垃圾回收的语言来说,怎么还会有内存泄露? 概括来说,有以下三种原因:

    所用到的用 C 语言开发的底层模块中出现了内存泄露。

    代码中用到了全局的 list、 dict 或其它容器,不停的往这些容器中插入对象,而忘记了在使用完之后进行删除回收

    代码中有“引用循环”,并且被循环引用的对象定义了__del__方法,就会发生内存泄露。

    为什么循环引用的对象定义了__del__方法后collect就不起作用了呢?

    gc模块最常使用的方法就是gc.collect()方法,使用collect方法对循环引用的对象进行垃圾回收。

    如果我们在类中重载了__del__方法。__del__方法定义了在用del语句删除对象时除了释放内存空间以外的操作。

    一般而言,在使用了del语句的时候解释器首先会看要删除对象的引用计数,如果为0,那么就释放内存并执行del方法。

    在这里,首先del语句出现时本身引用计数就不为0(因为有循环引用的存在),所以解释器不释放内存;

    再者,执行collect方法时应该会清除循环引用所产生的无效引用计数从而达到del的目的,对于这两个循环引用对象而言,

    python无法判断调用它们的del方法时会不会要用到对方那个对象,比如在进行b.del()时可能会用到b._a也就是a,如果在那之前a已经被释放,那么就彻底GG了。

    为了避免这种情况,collect方法默认不对重载了del方法的循环引用对象进行回收,而它们俩的状态也会从unreachable转变为uncollectable。由于是uncollectable的,自然就不会被collect处理,所以就进入了garbage列表。

    2、内存泄露的诊断思路

    无论是哪种方式的内存泄露,最终表现的形式都是某些 python 对象在不停的增长;因此,首先是要找到这些异常的对象。

    3、诊断步骤

    用到的工具: gc 模块和 objgraph 模块

    gc模块 是Python的垃圾收集器模块,gc使用标记清除算法回收垃圾

    objgraph 是一个用于诊断内存问题的工具

    1、 在服务程序的循环逻辑中,选择出一个诊断点

    2、 在诊断点,插入如下诊断语句

    import gc

    import objgraph

    ### 强制进行垃圾回收

    gc.collect()

    ### 打印出对象数目最多的 50 个类型信息

    objgraph.show_most_common_types(limit=50)

    4、检查统计信息,找到异常对象

    运行加入诊断语句的服务程序,并将打印到屏幕上的统计信息重定向到日志中。运行一段时间后,就可以来分析日志,看看哪些对象在不停的增长。

    比如,排查结果可能是:

    一个多线程程序,多个线程作为生产者,一个线程作为消费者,通过将一个 tuple 对象送入异步队列进行通信。

    由于消费者的处理速度跟不上生产者的速度,又没有进行同步, 导致异步队列中的对象越来越多。

    二、内存溢出

    1、内存溢出原因

    内存中加载的数据量过于庞大,如一次从数据库取出过多数据

    集合类中有对对象的引用,使用完后未清空,产生了堆积,使得JVM不能回收

    代码中存在死循环或循环产生过多重复的对象实体

    使用的第三方软件中的BUG

    启动参数内存值设定的过小

    2、内存溢出的解决方案

    第一步,修改JVM启动参数,直接增加内存(-Xms,-Xmx参数一定不要忘记加)

    第二步,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误

    第三步,对代码进行走查和分析,找出可能发生内存溢出的位置

    重点排查以下几点:

    检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

    检查代码中是否有死循环或递归调用。

    检查是否有大循环重复产生新对象实体。

    检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

    第四步,使用内存查看工具动态查看内存使用情况

    三、内存泄漏和内存溢出的区别

    内存溢出是指向JVM申请内存空间时没有足够的可用内存了,就会抛出OOM即内存溢出。

    内存泄漏是指,向JVM申请了一块内存空间,使用完后没有释放,由于没有释放,这块内存区域其他类加载的时候无法申请,

    同时当前类又没有这块内存空间的内存地址了也无法使用,相当于丢了一块内存,这就是内存泄漏。

    值得注意的是内存泄漏最终会导致内存溢出,很好理解,内存丢了很多最后当然内存不够用了。

    以上就是Python内存泄漏和内存溢出的解决方案的详细内容,更多关于Python内存泄漏和内存溢出的资料请关注云海天教程其它相关文章!

    原文链接:https://www.cnblogs.com/Zzbj/p/13532156.html

    展开全文
  • 今天在部署实验室项目时,发现项目在后台运行一个晚上后内存增长了近3g。考虑到目前的数据量较小,真正...在分析内存泄露之前需要先了什么情况会导致内存泄露.具体内容可以参照如下几篇博客:检测内存泄露接下来检测...

    今天在部署实验室项目时,发现项目在后台运行一个晚上后内存增长了近3g。考虑到目前的数据量较小,真正部署到线上时系统很可能因为OOM而被kill掉,因此进行了长达一天的debug与问题解决。

    python 内存泄露

    python的垃圾回收采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。

    在分析内存泄露之前需要先了什么情况会导致内存泄露.具体内容可以参照如下几篇博客:

    检测内存泄露

    接下来检测下程序中是否出现了内存泄露,pympler工具可以很容易看到内存的使用情况,用法如下

    import objgraph

    import schedule

    from pympler import tracker, muppy, summary

    tr = tracker.SummaryTracker()

    def dosomething():

    print "memory total"

    all_objects = muppy.get_objects()

    sum1 = summary.summarize(all_objects)

    summary.print_(sum1)

    print "memory difference"

    tr.print_diff()

    # ........ 爬取任务

    pass

    schedule.every(1).minutes.do(dosomething)

    对我的程序进行分析,可以看到如下的输出结果,可以看到程序存在缓慢的内存泄露

    markdown-img-paste-20200409074218734.png

    1180486-20200409085540610-1696911890.png

    定位内存泄露位置

    接下来要分析是那些对象导致内存泄露的.

    相关的工具如下:

    gc: python 内置模块, 函数少功能基本, 使用简单.

    objgraph: 可以绘制对象引用图, 对于对象种类较少, 结构比较简单的程序适用.

    guppy: 可以用来打印出各种对象各占用多少空间, 如果python进程中有没有释放的对象, 造成内存占用升高, 通过guppy可以查看出来. 但仅支持python2.

    pympler: 可以统计内存里边各种类型的使用, 获取对象的大小.

    下边是两个比较好用的工具,比上述的工具更为方便:

    pyrasite

    pyrasite 是1个可以直接连上一个正在运行的python程序, 打开一个类似ipython的交互终端来运行命令来检查程序状态.

    注: pyrasite使用之前需要在root用户下运行命令echo 0 > /proc/sys/kernel/yama/ptrace_scope后才能正常使用

    pyrasite里边有一个工具叫pyrasite-memory-viewer, 功能和guppy差不多, 不过可以对内存使用统计和对象之间的引用关系进行快照保存, 很易用也很强大.运行命令为 pyrasite-memory-viewer

    tracemalloc

    可以直接看到哪个(哪些)对象占用了最大的空间, 这些对象是谁, 调用栈是啥样的, python3直接内置, python2如果安装的话需要编译

    最终我定位到问题出现在我调用的hanlp2.0,这个库用于项目中地名识别,巧的是我在hanlp2的issue里发现了相似的问题pipeline添加自定义function后, 循环使用内存溢出,luoy2用了tracemalloc 定位到tokenizer和tagger在pipline方式后循环调用出现了内存泄露的现象。如下是何博士在issue中给出的解释:

    现在任务管理器中Python的内存已经涨到5个G了

    fasttext可能本身就要占用几个G。是增长量达到5个G吗?

    如果是的话是不是就是tf2的bug, 因为据汇报tf1.15 - 没有上述问题。

    可能有关系,有人说 I'm also still facing the same issue with TensorFlow 2.1.0.,也有人说 Still facing this problem in tf-nightly-gpu 2.2.0.dev20200307

    不过我没有在hanlp.com的服务器上观察到内存泄露的情况。跟python代码不同,我用的是tensorflow_serving提供服务,从上线到现在没有重启过。

    已确定是TensorFlow的问题,正在等TF社区回复。

    尝试解决

    在本地测试了如下的代码,并未生效,

    del recognizer

    del pipline

    print(gc.garbage)

    gc.collect()

    gc.garbage 返回为[], 奇怪的是我虽然尝试过不使用pipline的方式, 此时使用sys.getrefcount(recognizer),返回的recognizer的引用计数为2,但gc.garbage返回仍为[]。这里关于gc回收的接口参照如下的文档

    由于急着部署项目,只能先考虑备选方案。这里测试对pyhanlp,pytlp,lac进行了测试,感觉百度的lac命名实体识别功能较强。因此将项目中的地名识别模型做了替换。如下是对lac进行的泄露测试,可以看到内存泄露问题解决了。 另外惊喜的是,lac的基础模型不仅效果而且处理速度极快。

    1180486-20200409085612971-338490483.png

    参考

    展开全文
  • Java内存泄露解决方案

    2010-10-17 18:20:34
    Java 内存泄露 解决方案 outofmemoryException 从实践获取真理
  • 一、内存泄漏像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题。对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。1、...

    一、内存泄漏

    像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题。

    对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。

    1、内存泄露的原因

    对于 python 这种支持垃圾回收的语言来说,怎么还会有内存泄露? 概括来说,有以下三种原因:

    所用到的用 C 语言开发的底层模块中出现了内存泄露。

    代码中用到了全局的 list、 dict 或其它容器,不停的往这些容器中插入对象,而忘记了在使用完之后进行删除回收

    代码中有“引用循环”,并且被循环引用的对象定义了__del__方法,就会发生内存泄露。

    为什么循环引用的对象定义了__del__方法后collect就不起作用了呢?

    gc模块最常使用的方法就是gc.collect()方法,使用collect方法对循环引用的对象进行垃圾回收。

    如果我们在类中重载了__del__方法。__del__方法定义了在用del语句删除对象时除了释放内存空间以外的操作。

    一般而言,在使用了del语句的时候解释器首先会看要删除对象的引用计数,如果为0,那么就释放内存并执行del方法。

    在这里,首先del语句出现时本身引用计数就不为0(因为有循环引用的存在),所以解释器不释放内存;

    再者,执行collect方法时应该会清除循环引用所产生的无效引用计数从而达到del的目的,对于这两个循环引用对象而言,

    python无法判断调用它们的del方法时会不会要用到对方那个对象,比如在进行b.del()时可能会用到b._a也就是a,如果在那之前a已经被释放,那么就彻底GG了。

    为了避免这种情况,collect方法默认不对重载了del方法的循环引用对象进行回收,而它们俩的状态也会从unreachable转变为uncollectable。由于是uncollectable的,自然就不会被collect处理,所以就进入了garbage列表。

    2、内存泄露的诊断思路

    无论是哪种方式的内存泄露,最终表现的形式都是某些 python 对象在不停的增长;因此,首先是要找到这些异常的对象。

    3、诊断步骤

    用到的工具: gc 模块和 objgraph 模块

    gc模块 是Python的垃圾收集器模块,gc使用标记清除算法回收垃圾

    objgraph 是一个用于诊断内存问题的工具

    1、 在服务程序的循环逻辑中,选择出一个诊断点

    2、 在诊断点,插入如下诊断语句

    importgcimportobjgraph### 强制进行垃圾回收

    gc.collect()### 打印出对象数目最多的 50 个类型信息

    objgraph.show_most_common_types(limit=50)

    4、检查统计信息,找到异常对象

    运行加入诊断语句的服务程序,并将打印到屏幕上的统计信息重定向到日志中。运行一段时间后,就可以来分析日志,看看哪些对象在不停的增长。

    比如,排查结果可能是:

    一个多线程程序,多个线程作为生产者,一个线程作为消费者,通过将一个 tuple 对象送入异步队列进行通信。

    由于消费者的处理速度跟不上生产者的速度,又没有进行同步, 导致异步队列中的对象越来越多。

    二、内存溢出

    1、内存溢出原因

    内存中加载的数据量过于庞大,如一次从数据库取出过多数据

    集合类中有对对象的引用,使用完后未清空,产生了堆积,使得JVM不能回收

    代码中存在死循环或循环产生过多重复的对象实体

    使用的第三方软件中的BUG

    启动参数内存值设定的过小

    2、内存溢出的解决方案

    第一步,修改JVM启动参数,直接增加内存(-Xms,-Xmx参数一定不要忘记加)

    第二步,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误

    第三步,对代码进行走查和分析,找出可能发生内存溢出的位置

    重点排查以下几点:

    检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

    检查代码中是否有死循环或递归调用。

    检查是否有大循环重复产生新对象实体。

    检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

    第四步,使用内存查看工具动态查看内存使用情况

    三、内存泄漏和内存溢出的区别

    内存溢出是指向JVM申请内存空间时没有足够的可用内存了,就会抛出OOM即内存溢出。

    内存泄漏是指,向JVM申请了一块内存空间,使用完后没有释放,由于没有释放,这块内存区域其他类加载的时候无法申请,

    同时当前类又没有这块内存空间的内存地址了也无法使用,相当于丢了一块内存,这就是内存泄漏。

    值得注意的是内存泄漏最终会导致内存溢出,很好理解,内存丢了很多最后当然内存不够用了。

    展开全文
  • 记录 viewpager + fragment 导致的内存泄漏解决方案记录 viewpager + fragment 导致的内存泄漏解决方案尝试方案网上的方案以上就是 viewpager + fragment 内存泄漏的 2 中解决方案了,如果有其它方案,欢迎留言告知...

    记录 viewpager + fragment 导致的内存泄漏解决方案

    我的项目里面用到了 viewpager + fragment ,实现了多个页面左右滑动效果。使用过程中,leakCanary2 检测出了内存泄漏,可能存在泄漏的地方是存放 fagment 的集合 FragmentList。

    尝试方案

    既然内存泄漏指向了 FragmentList ,那就从它下手。

    在页面销毁时,清空 fragment 集合,手动释放内存

    void ondestroy(){
    	...
    	fragmentList.clear();
    	fragmentList = null;
    	...
    }
    

    和预期的不一样,虽然手动释放集合,但是内存泄漏问题还在,一模一样。太难了。

    网上的方案

    1. 通过 setOffscreenPageLimit()

      感觉这种方法比较局限,适用于 fragment 少的情况。具体做法就是,比如有5个 fragment ,就设置为 5。我在自己项目中测试过,的确没与内存泄漏了。

    2. 通过 PagerAdapter

    一般做法,都是通过集合保存 fragment 实例,然后传递到 adapter中。一直也这么做的,没想到会存在内存泄漏。

    	fragmentList.add(Fragment1.newInstance(0));
    	fragmentList.add(Fragment2.newInstance(1));
    	fragmentList.add(Fragment3.newInstance(2));
    	fragmentList.add(Fragment4.newInstance(3));
    	fragmentList.add(Fragment5.newInstance(4));
    

    新的做法是,将 fragment 的初始化,交给 adapter。

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return Fragment1.newInstance(position);
                case 1:
                    return Fragment2.newInstance(position);
                case 2:
                    return Fragment3.newInstance(position);
                case 3:
                    return Fragment4.newInstance(position);
                case 4:
                    return Fragment5.newInstance(position);
                default:
                    throw new RuntimeException("Fragment 创建异常");
            }
        }
    

    以上就是 viewpager + fragment 内存泄漏的 2 个解决方案了,如果有其它方案,欢迎留言告知。

    展开全文
  • Android ADT自带有内存检测工具,可以查看内存的占用情况,但是无法查看内存的详细信息, 我们需要安装Eclipse的内存分析工具MAT插件,来dump 出详细的内存情况,进行分析
  • 内存溢出和内存泄漏的区别  内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态。 内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上...
  •    不多说,直接上干货!     ...内存溢出和内存泄漏的区别 ... 内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或... 内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归...
  • 详细说明了QT检测内存泄漏的方法,包括检测工具及其安装方法和设置方法。
  • 结果发现并没有太好的解决方案。 先来分析下DialogFragment内存泄漏的原因: 此处可以看到是Handler持有的Message对象引起了内存泄漏,在Dialog源码中发现有一个mListenersHandler的变量,发现就是这个变量用来分发...
  • webview内存泄漏解决方案

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

    2018-11-14 13:47:18
    Java 内存泄露以及避免方法内存泄露:     是指在程序运行过程中会不断的分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证可以保证系统可以再次使用这些内存。...
  • 解决方案: 使用Application的Context就可以解决这类内存泄露的问题了 2. 非静态内部类引起内存泄露(包括匿名内部类)隐式持有主类;如 Handler。 解决方案: 解决方法是将内部类写成静态内部类,在静态内
  • 为什么会产生内存泄漏? Java内存泄漏指的是进程中某些对象(垃圾对象)已经没有使用价值了,但有另外一个正在使用的对象持有它的引用,从而导致它不能回收停留在堆内存中,这就产生了内存泄漏。无用的对象占据着...
  • android内存泄漏解决方案

    千次阅读 2017-06-21 17:11:43
    内存泄漏简介为什么有内存泄漏哪些场景容易内存泄漏ToastUtil传入Activity的Context 修改成使用getApplicationContext()mvp中,Presenter持有了Activity或者Fragment的强引用 ,如果在请求结束之前Activity或者...
  • 之前使用LeakCanary工具定位内存问题时候,发现系统输入法的内存泄漏,网上也有挺多解决方案
  • 关于NSURLSession内存泄露解决方案

    千次阅读 2016-11-09 09:39:59
    前些天,在使用NSURLSession的时候发生了严重的内存泄露问题,主要是 使用Xcode里面的Leak工具发现的,然后查看网上解决方法说,必须加入以下代码 - (void)dealloc { [self.session invalidateAndCancel]; } ...
  • 使用rxjava时演示内存泄漏解决方案的小示例应用程序
  • android-subscription-leaks 小样本应用程序展示了使用RxJava时的内存泄漏解决方案
  • 循环引用导致内存泄露解决方案

    千次阅读 2018-04-28 13:31:06
    循环引用:指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。...首先来看一个循环引用导致内存泄露的例子. #include <iostream> #...
  • 详解:Flutter内存泄漏解决方案

    千次阅读 2020-10-15 16:20:00
    背景众所周知,内存的高低是评判一款app的性能优劣的重要的指标之一。如何更简单的帮助开发者分析、暴露且解决内存泄漏问题,几乎是每一个平台或框架、开发者亟需的一个的"标配"...
  • WebView内存泄漏解决方案

    千次阅读 2018-01-19 10:27:01
    这些天总算把项目做的差不多了,但是还有一个问题没有解决,那就是WebView内存泄漏的问题,之前销毁WebView的方案是: if (mWebView != null) { mWebView.removeAllViews(); mWebView.destroy(); } 每次启动含有...
  • 公司里上了个项目,发现了pdfbox每次生成文件都大概要占用50m的内存,公司的云服务器成本控制只有8G,跑了一个小集群-nginx+tomcat为了保证业务稳定性的同时说一下有关于内存泄漏和读写文件加快速度的解决方案 ...
  • c++内存泄漏解决方案

    千次阅读 2017-11-24 11:11:18
    使用C++,不可避免的会遇到内存泄漏问题,遇到这个问题怎么办呢? 我是一般从这几个方面考虑: 第1种、显性的 new malloc delete free 是否匹配  这是最基本的,也就不多说了。 第2种、隐形的,这个就较为...
  • Android内存泄漏解决方案(OOM)

    千次阅读 2016-06-16 19:25:04
    为什么会有内存泄漏?一个不会被使用的对象,因为另一个正在使用的对象持有该对象的引用,导致它不能正常被回收,而停留在堆内存中,内存...当我们在解决内存泄漏的时候常常使用 LeakCanary工具,它是一个自动检测内存泄漏
  • Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,490
精华内容 32,196
关键字:

内存泄漏的解决方案