gpt4 book ai didi

覆盖对象时的 Perl 内存管理

转载 作者:行者123 更新时间:2023-12-01 05:15:56 25 4
gpt4 key购买 nike

我的问题是关于 Perl 如何在内部管理对象的数据。

在 Perl 中创建对象时,新的子例程通常会返回对祝福对象的引用。

以如下代码为例:

# Create a new object
my $object = Object->new(%data1);

# Create a new object with the same variable
$object = Object->new(%data2);

从第一次调用 new我们创建一个 $object引用了一些有福的%data1

Visual representation:

The "\" symbolizes a reference.


$object ════> \{bless %data1}

This would look as follows in memory:

The "&" symbolizes an address


MEMORY:
----------------------------------
&{bless %data1} ════> bless %data1

然后第二次调用new $object 的值改为引用其他一些有福的%data2

Visual representation:


$object ══/ /══> \{bless %data1}  # The connection to %data1 is broken

╚═══════════> \{bless %data2}

Now memory would look like this:


MEMORY:
----------------------------------
&{bless %data1} ════> bless %data1
&{bless %data2} ════> bless %data2

现在的问题是 $object不再存储引用 \{bless %data1} ,地址 &{bless %data1}并且存储在该地址的任何数据都将永远丢失。再也无法从脚本访问存储在该位置的数据了。

我的问题是。 . . Perl 是否足够聪明,可以删除存储在 &{bless %data1} 中的数据?一旦对该数据的引用永远丢失,或者 Perl 是否会将这些数据保存在内存中,从而可能导致内存泄漏?

最佳答案

给定

package Object {
sub new { my $class = shift; bless({ @_ }, $class) }
}

my $object = Object->new( a => 1, b => 2 );

在第二次分配之前,你有
           +============+   +==========+
$object -->[ Reference ---->[ Blessed ]
+============+ [ Hash ]
[ ] +==========+
[ a: --------->[ 1 ]
[ ] +==========+
[ ]
[ ] +==========+
[ b: --------->[ 2 ]
[ ] +==========+
+==========+

(箭头代表指针。)

Perl 使用引用计数来确定何时释放变量。作为赋值的一部分,名称(引用)当前引用的变量的引用计数将递减,导致它被释放[1]。这将减少哈希的引用计数,导致它被释放[1]。这将减少值的引用计数,导致它们被释放[1]。

在 Perl 中,当您有循环引用时会发生内存泄漏。
{
my $parent = Node->new();
my $child = Node->new();
$parent->{children} = [ $child ];
$child->{parent} = $parent;
}

在退出区 block 之前,您有
$parent               +----------------------------------------------------+
| | |
| +============+ +-->+==========+ |
+-->[ Reference -------->[ Blessed ] |
+============+ [ Hash ] |
[ ] +==========+ |
[ children --->[ Array ] |
[ ] [ ] +============+ |
+==========+ [ 0: --------->[ Reference ----+ |
[ ] +============+ | |
+==========+ | |
| |
$child +-------------------------------------------------+ |
| | |
| +============+ +-->+==========+ |
+-->[ Reference -------->[ Blessed ] |
+============+ [ Hash ] |
[ ] +============+ |
[ parent: ---->[ Reference ----------------------+
[ ] +============+
+==========+

存在 block 后,您有
                      +----------------------------------------------------+
| |
+-->+==========+ |
[ Blessed ] |
[ Hash ] |
[ ] +==========+ |
[ children --->[ Array ] |
[ ] [ ] +============+ |
+==========+ [ 0: --------->[ Reference ----+ |
[ ] +============+ | |
+==========+ | |
| |
+-------------------------------------------------+ |
| |
+-->+==========+ |
[ Blessed ] |
[ Hash ] |
[ ] +============+ |
[ parent: ---->[ Reference ----------------------+
[ ] +============+
+==========+

内存没有被释放,因为所有内容仍然被引用,因为有一个引用周期。由于您无法访问此结构(没有变量名引用其中的任何内容),因此这是内存泄漏。

  • 假设没有其他引用(指向)这些变量。
  • 关于覆盖对象时的 Perl 内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31971633/

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