perl - 为什么交叉引用造成的内存泄漏可以通过 Perl 中的显式重新分配来解决?

标签 perl

交叉引用会导致 Perl 中的内存泄漏,如下所示。

{
    my @a = qw(a b c);
    my @b = qw(a b c);
    # both reference count are 1
    push @a, \@b;
    # @b reference count is 2(from @b and via @a)
    push @b, \@a;
}
# @b reference count is 2(from via @a)

在这种情况下,我通过交叉引用了解内存泄漏。 但是内存泄漏可以通过像这样的显式重新分配来解决。

{
    my @a = qw(a b c);
    my @b = qw(a b c);
    # both reference count are 1
    push @a, \@b;
    # @b reference count is 2(from @b and via @a)
    push @b, \@a;
    @a = ();
}
# why is @b reference count 0?

@a 是词法作用域,所以我认为即使没有重新分配,@a 的引用也会无效,但前者会导致内存泄漏,后者不会,为什么?

最佳答案

你从

开始
@a                  @b
|   ARRAY           |   ARRAY
|   REFCNT=2        |   REFCNT=2
+-->+-----------+   +-->+-----------+
|   | +-------+ |   |   | +-------+ |
|   | | a     | |   |   | | a     | |
|   | +-------+ |   |   | +-------+ |
|   | | b     | |   |   | | b     | |
|   | +-------+ |   |   | +-------+ |
|   | | c     | |   |   | | c     | |
|   | +-------+ |   |   | +-------+ |
|   | |     --------+   | |     --------+
|   | +-------+ |       | +-------+ |   |
|   +-----------+       +-----------+   |
|                                       |
+---------------------------------------+

如果您要退出此处的范围,引用计数将降至 1,并且它们会泄漏。

@a = ();之后:

@a                  @b
|   ARRAY           |   ARRAY
|   REFCNT=2        |   REFCNT=1
+-->+-----------+   +-->+-----------+
|   |           |       | +-------+ |
|   |           |       | | a     | |
|   |           |       | +-------+ |
|   |           |       | | b     | |
|   |           |       | +-------+ |
|   |           |       | | c     | |
|   |           |       | +-------+ |
|   |           |       | |     --------+
|   |           |       | +-------+ |   |
|   +-----------+       +-----------+   |
|                                       |
+---------------------------------------+

请注意,@b 的引用计数从 2 变为 1。

作用域退出时,@a 的引用计数将降至 1,@b 的引用计数将降至零。[1] 这将释放 @b,这将导致 @a 的引用计数降至零。这将释放 @a

没有循环,所以没有内存泄漏。


  1. 至少在理论上是这样。在实践中,实际发生的情况与优化略有不同。但这些是内部细节,与此处无关。

关于perl - 为什么交叉引用造成的内存泄漏可以通过 Perl 中的显式重新分配来解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71632163/

相关文章:

perl - 使用 GD::Graph 绘制条形图

perl - 如何从另一个 PL/Perl 函数调用 PL/Perl 函数?

regex - 如何在两个已知标记之间进行最小匹配?

.net - 从 Perl 调用 .NET

regex - 如何匹配问号?

Perl hmac sha256 不同于 PHP 的使用包

regex - 如何从模块中导出正则表达式

regex - 在 Perl 中,如何使用正则表达式替换运算符替换子字符串中的非 ASCII 字符?

regex - 如何从 Perl 字符串中删除特定字符?

bash - 如何将字符串转换为修改后的十六进制表示?