为啥 Psyco 使用大量内存?
Posted
技术标签:
【中文标题】为啥 Psyco 使用大量内存?【英文标题】:Why does Psyco use a lot of memory?为什么 Psyco 使用大量内存? 【发布时间】:2009-09-17 11:18:42 【问题描述】:Psyco 是 Python 的专用编译器。 documentation states
Psyco 可以并且将会使用大量内存。
这种内存使用的主要原因是什么?大量的内存开销是 JIT 编译器的一般特性吗?
编辑:到目前为止,感谢您的回答。有三个可能的竞争者。
编写多个专用块,每个块都需要内存 动态编译源代码导致的开销 由于捕获足够的数据来进行动态分析而产生的开销问题是,哪一个是内存使用的主导因素?我有自己的看法。但是我要增加赏金,因为我想接受实际上正确的答案!如果有人可以证明或证明大部分内存在哪里使用,我会接受。否则,无论社区投票给谁,都会在赏金结束时自动接受。
【问题讨论】:
【参考方案1】:来自 psyco 网站“与传统 JIT 编译器方法的不同之处在于 Psyco 编写了相同块的多个版本(一个块是一个函数),通过专门化进行优化到某些种类的变量(“种类”可以表示一种类型,但它更通用)”
【讨论】:
【参考方案2】:“Psyco 使用您的程序操作的实际运行时数据来编写可能的多个版本的机器代码,每个版本都专门针对不同类型的数据。” http://psyco.sourceforge.net/introduction.html
许多 JIT 编译器使用静态类型语言,因此它们知道类型是什么,因此可以仅为已知类型创建机器代码。如果类型是多态的并优化更常见的路径,则更好的会进行动态分析;这也通常在具有动态类型的语言中完成†。 Psyco 似乎在对冲它的赌注,以避免进行完整的程序分析来确定可能是什么类型,或者通过分析来找出正在使用的类型。
† 我从来没有深入到 Python 来确定它是否具有动态类型(在使用该类型创建对象后可以在运行时更改其结构的类型),或者只是常见的实现在运行时检查类型;大多数文章只是对动态类型大加赞赏,而没有在 Python 的上下文中实际定义它。
【讨论】:
很好地使用 &dagger 来实现一个看起来合适的脚注! 您绝对可以在运行中将成员和函数添加到类的实例化中。您可以卸载、修改然后重新加载包含类的模块并开始使用新的模块。 这是否会更改具有该类的现有对象,还是仅在重新加载后创建新对象? 如果您更改类,创建的对象仍然存在于原始类中。您也可以直接修改一个对象,使其与原始类不同。【参考方案3】:目前 Psyco 的内存开销很大。随着时间的推移,我已经减少了一点,但这仍然是一个开销。 此开销与 Psyco 重写的 Python 代码量成正比;因此,如果您的应用程序有一些算法“核心”功能,那么这些就是您希望 Psyco 加速的功能 --- 而不是整个程序。
所以我认为大内存需求是由于它将源加载到内存中然后在运行时对其进行编译。您尝试编译的源代码越多,它需要的资源就越多。我猜想,如果它试图在此基础上对其进行优化,它会考虑多种可能的解决方案来尝试确定最佳情况。
【讨论】:
【参考方案4】:绝对 psyco 内存使用来自已编译的汇编程序块。 Psyco 有时会受到功能过度专业化的困扰,这意味着有多个版本的汇编程序 块。此外,这也是非常重要的,一旦分配了汇编程序块,psyco 永远不会释放 即使与之相关的代码已经死了。
如果你在 linux 下运行你的程序,你可以查看 /proc/xxx/smaps 来查看一个不断增长的匿名内存块,它位于与堆不同的区域。那是写下汇编程序的匿名映射部分,在没有 psyco 的情况下运行时当然会消失。
【讨论】:
以上是关于为啥 Psyco 使用大量内存?的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我从express发送一个简单的文件时,客户端会消耗大量内存?