- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据 Valgrind 的 memcheck 工具,如果我在函数中分配一个大的局部变量并使用 multiprocessing.Pool().apply_async()
启动该函数,子进程和子进程的堆大小主进程增加。为什么 main 的堆大小会增加?
我正在使用一个多处理池的工作人员,每个工作人员都将处理来自输入文件的大量数据。我想看看我的内存占用量如何根据输入文件的大小进行扩展。为此,我使用 memcheck 在 Valgrind 下运行我的脚本,并使用 this SO answer 中描述的技术。 。 (后来我了解到 Valgrind 的 Massif 工具更适合于此,因此我将继续使用它。)
memcheck 输出中有一些看起来很奇怪的东西,我希望帮助理解。
我在 Red Hat Linux 上使用 CPython 2.7.6,并像这样运行 memcheck:
valgrind --tool=memcheck --suppressions=./valgrind-python.supp python test.py
import multiprocessing
def mem_user():
tmp = 'a'*1
return
pool = multiprocessing.Pool(processes=1)
pool.apply_async(mem_user)
pool.close()
pool.join()
堆摘要(每个进程一个):
total heap usage: 45,193 allocs, 32,392 frees, 7,221,910 bytes allocated
total heap usage: 44,832 allocs, 22,006 frees, 7,181,635 bytes allocated
如果我将 tmp = 'a'*1
行更改为 tmp = 'a'*10000000
,我会得到以下摘要:
total heap usage: 44,835 allocs, 22,009 frees, 27,181,763 bytes allocated
total heap usage: 45,195 allocs, 32,394 frees, 17,221,998 bytes allocated
为什么两个进程的堆大小都会增加?我知道物体的空间是 allocated on the heap ,因此较大的堆对于其中一个进程当然是有意义的。但我希望子进程拥有自己的堆、堆栈和解释器实例,所以我不明白为什么在子进程中分配的局部变量也会增加 main 的堆大小。如果它们共享相同的堆,那么 CPython 是否实现了自己的 fork() 版本,不为子进程分配唯一的堆空间?
最佳答案
这个问题与fork
的方式无关。已实现。您可以亲眼看到 multiprocessing
来电 os.fork
,这是一个非常薄的包装 fork
.
那么,到底发生了什么?
编译器看到 'a' * 10000000
在您的源代码中并将其优化为 10000000 个字符的文字。这意味着模块对象现在长了 10000000 字节,并且由于它是在两个进程中导入的,因此它们都会变大。
要查看此内容:
$ python2.7
>>> def f():
... temp = 'a' * 10
...
>>> f.__code__.co_consts
(None, 'a', 10, 'aaaaaaaaaa')
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 3 ('aaaaaaaaaa')
3 STORE_FAST 0 (temp)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
请注意,编译器足够智能,可以添加 'aaaaaaaaaa'
到常量,但还不够聪明,无法删除 'a'
和10
。那是因为它使用了非常窄的窥视孔优化器。除此之外,它不知道您是否也在使用 'a'
在同一函数的其他地方,它不想从 co_consts
的中间删除值列出并返回并更新所有其他字节码以使用上移索引。
我实际上不知道为什么子进程最终会增长 20000000 字节而不是 10000000 字节。大概它最终会得到自己的模块副本,或者至少是代码对象,而不是使用从父进程共享的副本。但如果我尝试 print id(f.__code__)
或者其他什么,我在父级和子级中得到相同的值,所以......
关于python - 为什么 Python 子进程本地的对象分配会增加 main 的堆大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26131803/
因此,当使用“智能”时,当我想创建一个类时,它还会创建另外两个函数(不确定我是否正确调用了它们): class main { private: /* data */ public: m
我确实知道 C/C++ 和 Java 中使用的 main() 方法,但由于 main() 是用户定义的(因为 main() 中的代码是由用户定义的,它不能是预定义的方法) & 在 C/C++ 中,ma
这个问题在这里已经有了答案: What is a NullPointerException, and how do I fix it? (12 个答案) 关闭 7 年前。 我意识到这是一个常见错误,
您好,我是 jquery 和 javascript 的新手。我想做的是我有 3 个独立的 Main-Divs ex main-div1, main-div2, main-div-3 它们都是一个大盒子
我知道以前曾有人问过有关此错误的问题,但我的情况与其他人不同。我正在编写计算数据集的平均值、方差和标准差的代码。编译代码时我没有收到任何错误,但是当我尝试运行代码时,我收到如下错误: Exceptio
这个问题已经有答案了: What should main() return in C and C++? (19 个回答) Why is the type of the main function in
无效的输入流不起作用 - 每次我给出负的月份值时,它都会返回此异常。 代码: import java.util.Scanner; public class Main { public stat
我在 main() 中调用 main(),递归 10 次。现在,在使用 gdb (bt/backtrace) 进行调试时,我没有看到 main() 的多个帧。为什么? #include int mai
我有一个类 - A - 没有方法,只有主要方法。 在其他类(class) - B - 我需要调用那个 main.做什么最好?从使用的资源、时间和功耗以及效率来看? 从类 A 创建一个“a”对象并执行
鉴于 documentation以及对 earlier question 的评论,根据要求,我制作了一个最小的可重现示例,演示了这两个语句之间的区别: my %*SUB-MAIN-OPTS = :na
我有一个在 main 中声明并初始化的数组,名为 Edges。 我还在 main 中声明了一些访问名为 Edges 的数组的函数。 代码编译并运行。 为什么它有效?我认为 main 中声明的变量不是全
如果定义内容主要部分的最具语义性和可访问性的方式是标准,那么使用 ARIA 地标似乎是多余的元素。正在添加 role="main"到元素真的有必要吗? 最佳答案 并非所有现代浏览器都已经映射了 ari
我是 C 语言的新手(6 小时前开始),我知道有大量的在线引用资料,我应该(并且将会)详细查看,但现在,我有紧急情况需要帮助。我有一个包含以下文件的项目文件夹: boundary_val.c boun
我正在审查许多不同的 Java 程序,并试图弄清楚如何只更新一次而不是两次更新对程序名称的引用。有没有办法在单个终端命令中使用变量? :S 我试图改进的命令是这样的形式: javac Main.jav
我已经创建了一个工作线程, Thread thread= new Thread(runnable); thread.start(); 我在工作线程中打印这个; Log.d("SessionTh
import java.awt.*; import java.awt.event.*; import java.io.*; import java.lang.*; public class Main
这是我的 Main.java,它位于服务器套接字“get().logger().tag();”之后的部分我已经在实例中添加了所有这些,我真的不确定它出了什么问题。 public class Main
我在 http://www.hackerearth.com/problem/algorithm/roys-life-cycle/ 上测试了我的程序。但是,我总是收到错误:在类 ActivityTime
我想要一个脚本来运行从模块导出的子例程,导出的子程序在脚本中作为 MAIN 运行。该子例程做了我想做的所有事情,除了它返回结果而不是打印它。 RUN-MAIN 似乎实现了我的大部分目标,但我不确定如何
java中有什么具体原因吗,main方法应该是小写字母 是的“主要”和“主要” 编译完成 public class ManiMethod { public static void main(S
我是一名优秀的程序员,十分优秀!