gpt4 book ai didi

Perl:如何在不访问 Perl 变量的情况下释放为标量分配的内存?

转载 作者:IT王子 更新时间:2023-10-28 23:36:05 24 4
gpt4 key购买 nike

这个问题与 answer 相关。给前任question about memory handling由 Perl。我了解到可以通过在可用标量上显式使用 undef 函数并使用 Devel::PeekDevel::Size< 在 Perl 中释放内存 或这样的人可以看到为一个标量分配了多少内存。在所有这些情况下,调试的标量都在其范围内使用。

但是是否可以在 Perl 解释器的级别上调试变量范围之外的分配内存之类的东西?比如在当前解释器中为所有标量的“事物”搜索所有分配的内存并打印它们的相关数据,比如当前值等?

如果是这样的话,如果一个人已经拥有这些信息,那么一个人甚至能够释放已知的内存吗?就像在标量上调用 undef 一样,但没有标量,更底层的东西,例如 Devel::Peek 的那些“事物”输出。

我正在考虑的是在请求后执行 mod_perl 清理处理程序,扫描当前的 mod_perl 解释器以查找大块数据并手动释放它们。仅仅因为我认为分配的大块数据不再有用了,即使 Perl 不这么认为:

Finally and perhaps the biggest win is memory re-use: as calls are made into Perl subroutines, memory allocations are made for variables when they are used for the first time. Subsequent use of variables may allocate more memory, e.g. if a scalar variable needs to hold a longer string than it did before, or an array has new elements added. As an optimization, Perl hangs onto these allocations, even though their values "go out of scope".

https://perl.apache.org/docs/2.0/user/intro/overview.html#Threads_Support

我可以找到很多关于低级内存访问的监视和调试包,但还没有提示如何在 Perl 中的某些低级 Perl 结构上调用 undef 函数。没有任何 XS 之类的东西可能根本不可能......

最佳答案

is it possible to debug things like allocated memory outside the scope of variables

真的没有这样的内存。肯定需要在变量之外分配的任何内存。正如您自己指出的那样,为变量分配的内存构成了最“浪费”的空间。

but no hint yet how one could call something like the undef function on some low level Perl struct in Perl.

因为没有这样的结构体。

Just like calling undef on a scalar, but without the scalar, something more low level, like on those "things" output of Devel::Peek.

Devel::Peek 唯一的函数,Dump,输出东西in 变量。正如你所说,undef 是你想要清除这些的。


从上面,很明显你想知道如何释放与 subs 中的变量相关的内存。

您还忽略了一个事实,即许多运算符都有一个关联变量(称为“目标”),它们在其中返回结果。

方法 1

清除所有这些变量的一种简单方法是有选择地清除符号表 (%::)。这将有效地“卸载”每个模块。确保不要清除核心组件(perl -E'say for sort keys %::')。并且不要忘记清除 %INC 以便重新加载模块。

如果清除符号表是您想要采取的方法,那么尽早拍摄 %:: 的快照并在适当的时候恢复该快照可能会降低风险和耗时清除符号。

方法2

如果您不想重新加载模块,您可以尝试定位每个子,并取消定义它们的变量,然后取消定义其操作的变量。

一个子的变量存在于它的pads 中。 .方便的是,操作码目标也是如此。 sub 经历的每个递归级别都有一个填充。

给定一个对 sub 的引用,您可以在 sub 的 pad 中找到变量。您可以引用PadWalker有关如何执行此操作的示例。您实际上不能使用 PadWalker,因为它只为每个变量名返回一个变量,即使有多个变量(由于使用相同名称声明了多个变量,或者由于递归)。

捕获的变量和 我们的 变量应该保持不变。可以检测填充条目是否是其中之一。 (再次,请参阅 PadWalker。)

(显然,您也可以考虑释放潜艇的额外衬垫!)

你如何找到所有的潜艇?好吧,浏览符号表将为您提供其中的大部分。找到匿名的会比较棘手。

方法 3

最有效的方法是简单地终止 mod_perl 线程/进程。一个新的干净的将自动产生。它也是最容易实现的,因为它只是一个配置更改(将 MaxRequestsPerChild 设置为 1)。


另一种形式的内存浪费是内存泄漏。这又是一个大问题,所以我不涉及它。

关于Perl:如何在不访问 Perl 变量的情况下释放为标量分配的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39527245/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com