程序笔记   发布时间:2022-07-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Python垃圾回收和Linux Fork大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

在口袋助理看到了其他部门的同事针对Python2内存占用做的一点优化工作,自己比较感兴趣,遂记录下。

Linux fork简介

fork是Linux提供的创建子进程的系统调用。为了优化创建进程速度,Linux内核使用了Copy-on-Write的方式去创建进程,所谓copy-on-Write是指执行fork之后, 内核并不立即给子进程分配物理内存空间,而是让子进程的虚内存映射到父进程的物理内存。仅仅当子进程向地址空间中执行写入操作时,才给它分配一段物理内存。 通过这种方式既优化了进程创建的时间,又减少了子进程的内存占用。

Copy-On-Write策略增加Python多进程内存占用的原因

Python GC采用引用技术的方式去管理对每个对象的引用,每一个被GC跟踪的对象会由一个PyGC_Head的结构体去表示。如下所示,其中gc_refs就是每个对象的引用计数值, 当我们在子进程中读取父进程创建的对象的时候,就会导致子进程的虚地址空间中的gc_refs加1,从而触发了内核的缺页中断,这是内核就会给子进程创建新的物理内存。 仅仅是简单的读取操作就会导致新的内存空间产生。

/* GC information is stored BEFORE the object structure. */
typedef union _gc_head 
{
    struct {
        union _gc_head *gc_next;
        union _gc_head *gc_prev;
        Py_ssize_t gc_refs;
    } gc;
    long double dummy; /* force worst-case alignment */
} PyGC_Head;

解决办法

python3的解决方法

针对这个问题,Python3.7增加了三组API(有instagram团体提交的)[1]。

Python垃圾回收和Linux Fork

freeze用于将GC追踪的所有对象都移动到永生代(peRMANent generation),之后垃圾回收会忽略这些被设置为永生代的对象。

实际使用中,我们可以在父进程中执行freeze函数,然后子进程中使用和父进程共享的对象,这样对象的引用技术就不会增加,从而避免了COW的发生。

python2的解决方法

(1) 针对Python2,我们可以简单的把Python3的相关函数移植过来

(2) 使用multiprocessing.Array去共享数据。Array会从共享内存中取一段取存储数据,并不会增加引用技术值,从而触发COW。 实现方面,Array使用Posix共享内存 + mmap去实现。[3]

#!/usr/bin/env python
# coding=utf-8
from multiprocessing import Array
import os
import sys

def foo():
    shared_cache = Array('i', range(0, 100), lock=falsE)
    pid = os.fork()
    if pid > 0:
        print("parent:", sys.getrefcount(shared_cachE)) 
    elif pid == 0:
        print("child:", sys.getrefcount(shared_cachE))


foo()

1.https://instagram-ENGIneering.com/copy-on-write-friendly-python-garbage-collection-ad6ed5233ddf 2.https://llvllatrix.wordpress.com/2016/02/19/python-vs-copy-on-write/ 3.https://github.com/python/cpython/blob/main/Lib/multiprocessing/shared_memory.py

大佬总结

以上是大佬教程为你收集整理的Python垃圾回收和Linux Fork全部内容,希望文章能够帮你解决Python垃圾回收和Linux Fork所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。