Python内存管理

  1. Python是如何进行内存管理的?Python内存管理的优化方法?

    答:

    • Python的内存管理由Python解释器负责。

      • 引用计数机制

        当对象被引用时,计数增加 1;当对象不被引用时,计数减去 1;如果计数变成了 0,说明该对象没有被引用,可以删除该对象。可通过sys.getrefcount(a)获取变量a的引用计数。

      • 垃圾回收机制——引用计数为主,标记清除和分代回收为辅

        • 引用计数

          当一个对象的引用计数为0时,其将通过垃圾回收机制清除掉。

        • 标记清除

          为了解决循环引用的问题,引入了标记清除技术。解释器会定期执行一个循环检测器,找出不可访问对象的循环并清除。

        • 分代回收

          0/1/2代

      • 内存池机制

        • 小于256个字节的对象使用Pymalloc实现的分配器

        • 大于256个字节的对象使用系统的malloc分配大内存

          (Python 的内存池是一个金字塔模型:最顶层是用户对对象的直接操作,中间是分配小内存,最底层是大内存。)

    • 内存管理优化

      • 手动垃圾回收机制(关闭自动回收,根据情况手动触发)
      • 调高垃圾回收阈值(一定程度上避免垃圾回收,减少垃圾回收开销)
      • 避免循环引用
        • 手动解循环引用(在使用完对象后进行清除)
        • 使用弱引用(Python中有弱引用库weakref)
  2. 退出Python时,是否释放所有内存?

    答:不会释放所有内存。循环引用其他对象或引用全局命名空间的对象的情况下,并非完全释放,同时,也不会释放C库保留的内存部分。

  3. 内存溢出是什么?有哪些原因造成内存溢出?如何解决内存溢出?

    答:

    • 内存溢出Out of Memory(OOM)——系统已经不能再分配出所需的内存空间
      • 比如栈满时,进行入栈,造成上溢;栈空时,进行退栈,造成下溢
    • 造成内存溢出的原因
      • 一次性读取的数据量过大
      • 对象在使用完成后没有被清除
      • 代码编写时存在死循环或者循环过多产生重复的对象
      • 内存值设定太小
    • 解决内存溢出
      • 修改参数,增大内存值
      • 对代码进行review,找出可能发生内存溢出的位置
      • 使用内存管理工具动态查看内存使用情况
      • 查看以OutOfMemory开头的错误日志
  4. 内存泄漏是什么?内存泄漏有哪几种?如何避免内存泄漏?

    答:

    • 内存泄漏Memory Leak——对象不被回收,可能导致内存泄漏,即申请了内存空间,使用完后却未释放资源。

    • 内存泄漏分类

      • 常发性内存泄漏:发生内存泄漏的代码会被多次执行到,每执行一次造成内存泄漏一次。

      • 偶发性内存泄漏:发生内存泄漏的代码偶尔被执行到,每执行一次造成内存泄漏一次。

        (常发性和偶发性是相对的)

      • 一次性内存泄漏:某段代码只会被执行一次,内存泄漏只发生一次。

      • 隐式内存泄漏:某段代码在运行过程中不断地占用内存,直到结束时才释放。

    • 避免内存泄漏

      • 不使用对象时就删除对象
      • 通过gc模块查看不能回收的对象的相关信息,做对应的处理
      • 通过sys.getrefcount(a)查看引用计数情况
posted @ 2020-07-30 21:03  guguda  阅读(137)  评论(0)    收藏  举报