覆盖对象时的Perl内存管理 [英] Perl memory management when overwriting objects

查看:86
本文介绍了覆盖对象时的Perl内存管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My question is about how Perl manages the data of objects internally.

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

When creating objects in Perl, the new subroutine will typically return a reference to a blessed object.

以以下代码为例:

Take the following code as an example:

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

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


从第一个电话到new,我们创建一个$object,它引用一些有福的%data1


From the first call to new we create an $object that references some blessed %data1

视觉表示:

Visual representation:

"\"表示参考.

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

在内存中看起来如下:

This would look as follows in memory:

&"象征一个地址

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


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


Then with the second call to new the value of $object is changed to reference some other blessed %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}以及在该地址存储的所有数据永远丢失.不再有办法从脚本访问存储在该位置的数据.


The problem is now that $object no longer stores the reference \{bless %data1}, the address &{bless %data1} and any data stored at this address is lost forever. There is no possible way to access the data stored at that location from the script anymore.

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

My question is . . . Is Perl smart enough to remove the data stored in &{bless %data1} once the reference to this data is lost forever, or will Perl keep that data in memory potentially causing a memory leak?

推荐答案

给出

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

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

在第二次分配之前,您已经

Before the second assignment, you have

           +============+   +==========+
$object -->[ Reference ---->[ Blessed  ]
           +============+   [ Hash     ]
                            [          ]   +==========+
                            [ a: --------->[ 1        ]
                            [          ]   +==========+
                            [          ]
                            [          ]   +==========+
                            [ b: --------->[ 2        ]
                            [          ]   +==========+
                            +==========+

(箭头代表指针.)

Perl使用引用计数来确定何时释放变量.作为分配的一部分,当前由名称(引用)引用的变量的引用计数将减少,从而使其释放 [1] .这将删除哈希的引用计数,从而使它被释放 [1] .这将删除值的引用计数,从而释放它们 [1] .

Perl uses reference counting to determine when to free variables. As part of the assignment, the reference count of the variable currently referenced by the name (the Reference) will be decremented, causing it to be freed[1]. This will drop the reference count of the hash, causing it to be freed[1]. This will drop the reference count of the values, causing them to be freed[1].

在Perl中,拥有循环引用会导致内存泄漏.

In Perl, you get memory leaks when you have cyclic references.

{
   my $parent = Node->new();
   my $child = Node->new();
   $parent->{children} = [ $child ];
   $child->{parent} = $parent;
}

在退出街区之前,您已经

Before exiting the block, you have

$parent               +----------------------------------------------------+
 |                    |                                                    |
 |   +============+   +-->+==========+                                     |
 +-->[ Reference -------->[ Blessed  ]                                     |
     +============+       [ Hash     ]                                     |
                          [          ]   +==========+                      |
                          [ children --->[ Array    ]                      |
                          [          ]   [          ]   +============+     |
                          +==========+   [ 0: --------->[ Reference ----+  |
                                         [          ]   +============+  |  |
                                         +==========+                   |  |
                                                                        |  |
$child                +-------------------------------------------------+  |
 |                    |                                                    |
 |   +============+   +-->+==========+                                     |
 +-->[ Reference -------->[ Blessed  ]                                     |
     +============+       [ Hash     ]                                     |
                          [          ]   +============+                    |
                          [ parent: ---->[ Reference ----------------------+
                          [          ]   +============+
                          +==========+

存在该区块后,您拥有

                      +----------------------------------------------------+
                      |                                                    |
                      +-->+==========+                                     |
                          [ Blessed  ]                                     |
                          [ Hash     ]                                     |
                          [          ]   +==========+                      |
                          [ children --->[ Array    ]                      |
                          [          ]   [          ]   +============+     |
                          +==========+   [ 0: --------->[ Reference ----+  |
                                         [          ]   +============+  |  |
                                         +==========+                   |  |
                                                                        |  |
                      +-------------------------------------------------+  |
                      |                                                    |
                      +-->+==========+                                     |
                          [ Blessed  ]                                     |
                          [ Hash     ]                                     |
                          [          ]   +============+                    |
                          [ parent: ---->[ Reference ----------------------+
                          [          ]   +============+
                          +==========+

没有释放内存,因为由于存在引用循环,因此仍在引用所有内容.由于您无法访问此结构(没有变量名引用其中的任何内容),因此会导致内存泄漏.

The memory didn't get freed because everything is still being referenced because there's a reference cycle. Since you have no way of accessing this structure (no variable names reference anything in it), it's a memory leak.

  1. 假设没有其他内容引用(指向)这些变量.

这篇关于覆盖对象时的Perl内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆