日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python垃圾回收及Linux?Fork_python

作者:令狐蔥dennis ? 更新時間: 2022-03-28 編程語言

前言:

在口袋助理看到了其他部門的同事針對Python2內存占用做的一點優化工作,自己比較感興趣,遂記錄下。

1.Linux fork簡介

fork是Linux提供的創建子進程的系統調用。為了優化創建進程速度,Linux內核使用了Copy-on-Write的方式去創建進程,所謂Copy-on-Write是指執行fork之后,
內核并不立即給子進程分配物理內存空間,而是讓子進程的虛內存映射到父進程的物理內存。僅僅當子進程向地址空間中執行寫入操作時,才給它分配一段物理內存。
通過這種方式既優化了進程創建的時間,又減少了子進程的內存占用。

1.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;

3.解決辦法

python3的解決方法:

針對這個問題,Python3.7增加了三組API(有instagram團體提交的)[1]。

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()

到此這篇關于Python垃圾回收及Linux Fork的文章就介紹到這了,更多相關Python垃圾回收及Linux Fork內容請搜索AB教程網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持AB教程網!

參考:

原文鏈接:https://www.cnblogs.com/dennis-wong/p/15782824.html

欄目分類
最近更新