delete object

Discussion in 'Perl Misc' started by George Mpouras, Apr 25, 2012.

  1. I have create a class witht some properties and methods
    I create a new object and do some stuff
    At the end I call a custom method called $obj->Close();
    the Close is like this

    sub Close
    {
    my $self = shift;
    my $class = ref $self || $self;
    $class = __PACKAGE__ if $class eq '';
    ref $self || die
    ......
    $self = {};
    undef $self;
    }

    Unfortunately after calling the Close the
    use Data::Dumper; print Dumper($obj);
    at my main program is still full of data . What I have to do inside the
    module , so when I call the Close the $obj to be empty ?
    George Mpouras, Apr 25, 2012
    #1
    1. Advertising

  2. George Mpouras

    Willem Guest

    George Mpouras wrote:
    ) I have create a class witht some properties and methods
    ) I create a new object and do some stuff
    ) At the end I call a custom method called $obj->Close();
    ) the Close is like this
    )
    ) sub Close
    ) {
    ) my $self = shift;
    ) my $class = ref $self || $self;
    ) $class = __PACKAGE__ if $class eq '';
    ) ref $self || die
    ) .....
    ) $self = {};
    ) undef $self;
    ) }
    )
    ) Unfortunately after calling the Close the
    ) use Data::Dumper; print Dumper($obj);
    ) at my main program is still full of data . What I have to do inside the
    ) module , so when I call the Close the $obj to be empty ?

    This should work:

    %$self = ();

    But *why* do you want the $obj to be empty? There is no need to do that.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Apr 25, 2012
    #2
    1. Advertising

  3. George Mpouras

    Tim McDaniel Guest

    In article <jn93hf$1b8$>,
    George Mpouras <> wrote:
    >I have create a class witht some properties and methods
    >I create a new object and do some stuff
    >At the end I call a custom method called $obj->Close();
    >the Close is like this
    >
    >sub Close
    >{
    >my $self = shift;
    >my $class = ref $self || $self;
    > $class = __PACKAGE__ if $class eq '';
    >ref $self || die
    >.....
    >$self = {};
    >undef $self;
    >}


    Almost everybody finds it helpful to indent their code inside {...}.

    >Unfortunately after calling the Close the
    >use Data::Dumper; print Dumper($obj);
    >at my main program is still full of data . What I have to do inside
    >the module , so when I call the Close the $obj to be empty ?


    I want to echo Willem's comment that
    %$self = ();
    should work.

    The reason why:

    {...} in a value context produces a reference to a hash table. When
    you assign references like "$b = Frog->new()", $b points to the hash
    table in memory. If you later do "$c = $b", $c and $b point to the
    same area. If you later do "$b = {}", then $b points to a different
    (empty) hash table, but $c still points to the old one.

    But for a different thing: if you manipulate what $b or $c point to,
    then using $b and $c see the effect.
    $c = $b;
    $b->{'trireme'} = 3;
    then
    $c->{'trireme'}
    evaluates to 3 also.

    That is why
    $self = {};
    undef $self;
    do nothing to $obj. They make $self point to a new empty hash table,
    or make it undef, which does not change $obj.

    That is why
    %$self = ();
    should work. That does not change $self. It changes what $self
    points to. Since $obj points to the same thing, it also see the
    changes.

    I also wonder a little bit why you worry about this. When Perl sees
    that an object has no more references to it, then it knows that it is
    impossible for that object to ever be used again, and it cleans up the
    space when it thinks it's convenient. That is usually good enough.
    Certainly the other way, making the programmer clean up old objects,
    has been demonstrated again and again to be a lot of trouble and hard
    to do correctly in all cases. In almost all cases, you just want Perl
    to do the cleanup reliably for you ... unless there is some other
    reason.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 25, 2012
    #3
  4. George Mpouras

    Tim McDaniel Guest

    In article <>,
    Ben Morrow <> wrote:
    >Instead, write a DESTROY method (if you need one)


    To expand on that: my understanding is that a DESTROY method is very
    rarely needed -- for example, if there's an external connection that
    must be closed cleanly. If all you are worried about is internal
    storage, like the contents of a hash table, then I don't know of a
    reason to have a DESTROY method: I think it will be called only when
    there are no more references to the object, so as long as $obj still
    has a reference to the object, it won't get called.

    >and then just
    >
    > undef $obj;
    >
    >when you want to destroy it.


    Note that that's in the caller, getting rid of the more persistent
    reference to the data.

    >Most of the time you don't need to: you can just let it go out of
    >scope.


    That's a short form of what I wrote.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 25, 2012
    #4
  5. Ben Morrow <> writes:
    > Quoth :
    >> In article <>,
    >> Ben Morrow <> wrote:
    >> >Instead, write a DESTROY method (if you need one)

    >>
    >> To expand on that: my understanding is that a DESTROY method is very
    >> rarely needed -- for example, if there's an external connection that
    >> must be closed cleanly. If all you are worried about is internal
    >> storage, like the contents of a hash table, then I don't know of a
    >> reason to have a DESTROY method: I think it will be called only when
    >> there are no more references to the object, so as long as $obj still
    >> has a reference to the object, it won't get called.

    >
    > You also need DESTROY when the object has internal circular references,
    > since they won't be collected until the cycle is explicitly broken.


    Provided that 'an object' has the only reference to some self-referential
    structure, the DESTROY method can be used to 'break the circle' so
    that the affected objects are destroyed, too. But that's rare enough
    to be considerde coincedence.

    > Nowadays you can often avoid this by using weakrefs, though it's not
    > always easy to pick the right ref to weaken. (This is a consequence of
    > Perl using reference counts rather than a proper garbage collector.)


    As a consequence of the Perl using proper garbage collection, instead
    of something designed in an academic ivory tower in order to design
    academic ivory tower problems which rarely occur in practice, it is
    usable for for something other than academic ivory navel-gazing, since
    this usually involves dealing with all kinds of 'external objects'
    beyond the reach of the garbage ivory academics collector and this
    'dealing with' requires programmer control over both initialization
    and finalization, even if this 'external object' is something as
    mundane as a file (fans of 'proper garbage collection' usually
    maintain that it is much properer when it solely deals with memory
    while all other resources are to be managed with explicit code). There
    also other, nice side effects, eg, the memory requirements of Perl
    compared 'something proper' (such as Java) are really frugal because
    memory can be reused as soon as it became unused, not as soon as there
    really is no other choice. This is, of course, not really feature
    because it doesn't help Oracle selling high-end minicomputers ...
    and so on.

    Is there any kind of Kool-Aid on this planet you didn't drink?
    [just wondering ...]
    Rainer Weikusat, Apr 25, 2012
    #5
  6. This should work:

    %$self = ();

    But *why* do you want the $obj to be empty? There is no need to do that.

    it works partially . $obj is still a blessed object;
    There is a need for this. What I am doing at the main script is complex and
    objects are looking at each other status.
    What I decide to do is


    sub Close {
    ....
    %{$self} = ();
    return {};
    }


    and at the calling script
    $obj = $obj->Close;
    George Mpouras, Apr 25, 2012
    #6
  7. Ο "Ben Morrow" έγÏαψε στο μήνυμα
    news:...


    What on *Earth* are you doing here? Do you know aht any of this is
    supposed to do?


    Let me think, log(x**7)**(1/2) - 3 maybe ?
    George Mpouras, Apr 25, 2012
    #7
  8. That is why
    $self = {};
    undef $self;
    do nothing to $obj. They make $self point to a new empty hash table,
    or make it undef, which does not change $obj.

    That is why
    %$self = ();
    should work. That does not change $self. It changes what $self
    points to. Since $obj points to the same thing, it also see the
    changes.


    Very explanatory, thanks Tim.
    George Mpouras, Apr 25, 2012
    #8
  9. George Mpouras

    Tim McDaniel Guest

    In article <jn9hoe$1q4i$>,
    George Mpouras <> wrote:
    >This should work:
    >
    > %$self = ();
    >
    >But *why* do you want the $obj to be empty? There is no need to do that.
    >
    >it works partially . $obj is still a blessed object;
    >There is a need for this. What I am doing at the main script is complex and
    >objects are looking at each other status.
    >What I decide to do is
    >
    >sub Close {
    >...
    >%{$self} = ();
    >return {};
    >}
    >
    >and at the calling script
    >$obj = $obj->Close;


    By "looking at each other's status", do you mean that other objects
    have references to the same object? If not, and if you're willing to
    change the caller, maybe you should be able to do
    undef $obj;
    and forget about doing anything else.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 25, 2012
    #9
  10. Ï "Tim McDaniel" Ýãñáøå óôï ìÞíõìá news:jn9iht$bmj$...

    In article <jn9hoe$1q4i$>,
    George Mpouras <> wrote:
    >This should work:
    >
    > %$self = ();
    >
    >But *why* do you want the $obj to be empty? There is no need to do that.
    >
    >it works partially . $obj is still a blessed object;
    >There is a need for this. What I am doing at the main script is complex and
    >objects are looking at each other status.
    >What I decide to do is
    >
    >sub Close {
    >...
    >%{$self} = ();
    >return {};
    >}
    >
    >and at the calling script
    >$obj = $obj->Close;


    By "looking at each other's status", do you mean that other objects
    have references to the same object? If not, and if you're willing to
    change the caller, maybe you should be able to do
    undef $obj;
    and forget about doing anything else.


    There are no cross references , only simple read properties between objects.
    Yes undef $obj is enough after all. but I would like also to free some
    memory !


    --
    Tim McDaniel,
    George Mpouras, Apr 25, 2012
    #10
  11. George Mpouras

    Tim McDaniel Guest

    In article <jn9j89$1v7s$>,
    George Mpouras <> wrote:
    >Yes undef $obj is enough after all. but I would like also to free
    >some memory !


    I think that you did not understand the previous messages on garbage
    collection. After you remove the last reference to some data, Perl
    will free that memory automatically at some time. Also, unless there
    is MUCH MUCH memory in an object, you should not bother to free it
    yourself.

    --
    Tim McDaniel,
    Tim McDaniel, Apr 25, 2012
    #11
  12. I understand about garbage collector, theory is good but practice is
    different.
    try this command to check memory usage by perl
    watch "ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS | grep -i perl"

    my @array;
    push @array, $_ foreach 1 .. 20_000_000;

    # if do nothing 816136 perl mem.pl
    #undef @array; # with this 553996 perl mem.pl
    #@array = (); # with this 816140 perl mem.pl

    print "press any key to continue"; getc;
    George Mpouras, Apr 25, 2012
    #12
  13. Perl will free it *immediately*, including calling ->DESTROY if it is
    defined.

    while your program is running it will not free a bit
    George Mpouras, Apr 25, 2012
    #13
  14. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> Ben Morrow <> writes:
    >> >
    >> > You also need DESTROY when the object has internal circular references,
    >> > since they won't be collected until the cycle is explicitly broken.

    >>
    >> Provided that 'an object' has the only reference to some self-referential
    >> structure, the DESTROY method can be used to 'break the circle' so
    >> that the affected objects are destroyed, too. But that's rare enough
    >> to be considerde coincedence.

    >
    > It's not at all rare: for instance, XML::Twig has circular refs, and a
    > ->dispose method to break them.


    I'm writing about using Perl for real-world problems, specifically,
    the real-world problems I used it for during the last 15 years or so,
    and there, circular references where a rare occurence. For obvious
    reasons, I can't comment on what people designed which
    self-referential datastructures for what reasons when implenting 1
    bazillion of 'generally useful' (aka 'generally useless') code
    libraries available for download from server a.b.c.d.

    >>> Nowadays you can often avoid this by using weakrefs, though it's not
    >>> always easy to pick the right ref to weaken. (This is a consequence of
    >>> Perl using reference counts rather than a proper garbage collector.)

    >>
    >> As a consequence of the Perl using proper garbage collection, instead
    >> of something designed in an academic ivory tower in order to design
    >> academic ivory tower problems which rarely occur in practice,

    >
    > When implementing large systems, Perl's refcounting causes problems in
    > practice.


    Problems which occur in 'large systems' are more often than not
    problems occuring because of 'the large system' which should usually
    rather be structured into independent components interacting with each
    other. Also, the interesting question is 'what precisely is a large
    system'? Eg, it is a safe assumption that a monolithic OS kernel is
    necessarily a larger 'integrated system' than most sensibly designed
    applications. Yet, reference counting is (and - AFAIK - has always
    been) the memory management strategy of choice for kernels (BTW, the
    'large system' is another classic ivory-tower fad -- if people think
    they need to implement 'large systems' then they have to find a way to
    solve the problems related to that. And that they *believe* to need
    something in order to solve some problem they encountered [or believe
    they will encounter] doesn't turn that something into a categorical
    imperative).

    But this is more or less an aside: I two useful properties of
    referencing: It is deterministic and it can be used for all kinds of
    resources, not just memory. The first one is a conditio sine qua non
    for the more complicated problems I have to deal with because of the
    necessity to conform to 'some kind of protocol' wrt dealing with
    'external entities' such as database servers. And the second makes my
    (or anyone's) life much easier because there's generally no need to
    worry about explicit resource management -- an object dies as soon as
    it isn't used anymore and code tearing down whatever needs to be torn
    down, insofar not already included in Perl, will run automatically
    whenever this happens. A third one would be that it is possible to
    have live Perl objects which are temporarily not reachable from
    within the program, eg, send a pointer to some object through a kernel
    IPC channel to another part of the program, for instance, some
    top-level event loop, and ensure that it isn't deallocated by
    increasing its reference count. This can also be very convenient.

    > Internally, they cause *huge* problems: a large number of bugs
    > in perl turn out to be caused by a refcount which got too high or too
    > low somewhere.


    100% of all bugs in the perl implementation come from buggy code which
    happens to be part of it. That's not exactly surprising ...
    Rainer Weikusat, Apr 25, 2012
    #14
  15. >>>>> "Ben" == Ben Morrow <> writes:

    Ben> When implementing large systems, Perl's refcounting causes problems in
    Ben> practice. Internally, they cause *huge* problems: a large number of bugs
    Ben> in perl turn out to be caused by a refcount which got too high or too
    Ben> low somewhere.

    This is FUD. The only time you need to worry about refcounts is when
    you write circular-reference data structures. And when you're doing
    that, you know you are doing that.

    Just keep your data as a DAG, not a willy-nilly criss-cross, and it'll
    be easier to test *and* maintain.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
    See http://methodsandmessages.posterous.com/ for Smalltalk discussion
    Randal L. Schwartz, Apr 25, 2012
    #15
  16. On 04/25/2012 02:02 PM, Ben Morrow wrote:
    >
    >
    > When implementing large systems, Perl's refcounting causes problems in
    > practice.


    While I don't doubt that that is true, I've run into more problems with
    Java's garbage collector than I have with Perl's, and I've used Perl far
    far more.

    > Internally, they cause *huge* problems: a large number of bugs
    > in perl turn out to be caused by a refcount which got too high or too
    > low somewhere.


    Well, I'm sure mistakes can be made in the implementation of any technique.

    Xho
    Xho Jingleheimerschmidt, Apr 26, 2012
    #16
  17. George Mpouras

    Ivan Shmakov Guest

    >>>>> George Mpouras <> writes:

    > I understand about garbage collector, theory is good but practice is
    > different.


    > try this command to check memory usage by perl


    > watch "ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS | grep -i perl"


    Indeed, Perl doesn't seem to free all the space immediately.

    #!/usr/bin/perl

    # 1652 perl ...
    BEGIN { getc; }
    my @array = (1 .. (1 << 22));
    # 331360 perl ...
    # huh? 80 bytes per an integer?
    getc;
    print $#array, "\n"; # prints: 4194303
    undef @array;
    # 298640 perl ...
    getc;

    [...]

    --
    FSF associate member #7257
    Ivan Shmakov, Apr 26, 2012
    #17
  18. "George Mpouras" <>
    > I understand about garbage collector, theory is good but practice is
    > different.
    > try this command to check memory usage by perl
    > watch "ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS | grep -i perl"


    In the given context, this is a nonsense-test: The resident segment
    size is the amount of physical memory the kernel has presently
    allocated to this process. This number is going to be smaller than or
    equal the amount of virtual memory allocated to this process (code +
    stack + statically allocated data + 'dynamically allocated memory',
    VSZ). The latter may change if the process choses to 'shrink' the
    used portion of its virtual address space, eg, by munmapping some
    area/ file which was mmapped before or by lowering the 'break' (=>
    brk(2), sbrk(2)). Usually, this doesn't happen because userspace
    memory allocators will keep 'free' virtual memory they have already
    allocated in order to reuse it for future userspace memory allocation
    requests (there's no good reason for doing otherwise because, except
    on pathologically configured systems ["I wanted to kill the swap
    because it was there!!"], the kernel will redistribute physical memory
    among itself and other processes as it sees fit/ as the need arises).

    In addition to this, perl will also usually keep memory that was
    already allocated for some variable attached to that variable in case
    it might again be needed in future, cf

    ----------
    use Devel::peek;

    @a = 0 .. 1000000;
    @a = ();
    Dump(\@a);

    $s = join('', 0 .. 100000);
    $s = '';
    Dump(\$s);
    ----------
    Rainer Weikusat, Apr 26, 2012
    #18
  19. Ben Morrow <> writes:
    > Quoth Xho Jingleheimerschmidt <>:
    >> On 04/25/2012 02:02 PM, Ben Morrow wrote:


    [...]

    >> > Internally, they cause *huge* problems: a large number of bugs
    >> > in perl turn out to be caused by a refcount which got too high or too
    >> > low somewhere.

    >>
    >> Well, I'm sure mistakes can be made in the implementation of any technique.

    >
    > I'm not just talking about mistakes: if that was the only issue, they'd
    > have been found and fixed. The problem is that perl's internal data
    > structures consists of a rather complicated graph of objects (well,
    > structs), with necessary cross-references all over the place, and with
    > enormously varying lifetimes. The perl core is, in fact, a good example
    > of a system where Randal's suggestion to just keep your data in a DAG is
    > not practical.


    Naively counting lines of code, perl 5.10.1 figures as 574,000 and the
    core of Linux 2.6.36.4 (without architecture specific code and device
    drivers) has 2,132,318 which is about 3.72 times the size of the
    former (and the count is biased in favor of perl because it didn't
    cherry-pick anything there). So, how come that something which causes
    so 'huge problems' in a relatively small 'system' that some people
    consider it unworkable apparently works for a much larger system which
    is additionally forced to 'survive' in a signficantly less friendly
    environment? Could this perhaps be an instance of some (few) people
    confusing "we can't do it" with "it can't be done" (or, not entirely
    unlikely "they surely won't be able to do it" with "it is impossible"?)

    > For example, a bug which was fixed in 5.14 but before that will segfault
    > perl, probably back as far as 5.000:
    >
    > perl -MDevel::peek -e'my $x = sub { 1 };
    > delete $main::{__ANON__};
    > Dump $x;
    > '
    >
    > This segfaults because the sub holds a pointer to its glob, in this case
    > *__ANON__; but this pointer isn't refcounted, because (at least in the
    > named sub case) the glob also holds a pointer to the sub, so there would
    > be a cycle.


    Nope. This isn't refcounted because this would be pointless in case of
    a named sub since the glob already holds a refcounted pointer to the
    sub. For obvious reasons, a mechanism designed based on the assumption
    that there will always an 1:1 mapping between different kinds of
    objects can't just be 'extended' to the 1:n case without changes. Why
    does an anonymous sub have to have a pointer to a glob with a name in
    the symbol table to begin with? Minus "this happened to be the fastest
    way to tack it onto the existing code" of course? If this is a magic
    glob, why is it possible to delete from Perl code? Or why isn't this
    simply documented as 'the glob .... is used internally by perl and
    Perl code must not delete it'? Lastly, which actually useful
    functionally is provided by this example that is supposed to justify
    dumping other useful functionality?
    Rainer Weikusat, Apr 27, 2012
    #19
  20. On 2012-04-25 21:09, George Mpouras <> wrote:
    >
    > Perl will free it *immediately*, including calling ->DESTROY if it is
    > defined.
    >
    > while your program is running it will not free a bit


    That's not true.

    Perl will call free() immediately (in most cases - there are some cases
    where it keeps the memory because it expects to need it again soon).

    But what free does with the memory depends on the implementation of the
    malloc library. In the case of the GNU library the rules are (somewhat
    simplified):

    * Small objects (up to 128 kB) objects are allocated from the "heap" -
    a contiguous memory area just after the data segment. The heap can
    grow (if there is not enough unused memory in it) or shrink (if there
    is unused memory at the end), but it is always contiguous. If there
    are 3 MB of unused memory in the middle of it, that memory can not be
    returned to the OS. (But that memory is of course available for
    future malloc calls and the heap will only grow again after you've
    filled it up).

    * Larger objects are allocated individually via mmap. Because they have
    been individually requested from the OS, they can be (and are)
    individually returned to the OS.

    Most memory allocations that perl makes (SVs, strings, pads, ...) are
    small - they come from the heap and when they are freed they go back to
    the heap - they will be reused when perl needs more memory again, but
    the perl process won't shrink (unless you just happened to free enough
    memory at the end of the heap). But long strings and large arrays and
    hashes (only the array or hash itself, not its elements) come directly
    from the OS and will be returned to it immediately. So if those are
    freed the process does shrink.

    Other malloc implementations may differ.

    But the important point is that this is a function of the underlying
    malloc library, not the perl interpreter, and as a Perl programmer you
    have no control over that. The perl interpreter just calls free, whether
    you just let the object go out of scope or you called undef. The malloc
    library then decides what to do with the chunk of memory you just
    returned to it. The code you posted earlies almost certainly makes no
    difference, the result is just the same as if you just removed the last
    reference to the object.

    hp

    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Apr 28, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sandeep Grover

    delete on delete !

    Sandeep Grover, Jul 12, 2003, in forum: C++
    Replies:
    19
    Views:
    603
    Chris \( Val \)
    Jul 22, 2003
  2. HeroOfSpielburg
    Replies:
    1
    Views:
    373
    Alf P. Steinbach
    Aug 6, 2003
  3. 0to60
    Replies:
    4
    Views:
    304
    Jerry Coffin
    Dec 19, 2003
  4. Mathieu Malaterre

    delete NULL, what about delete[] NULL

    Mathieu Malaterre, Aug 17, 2004, in forum: C++
    Replies:
    2
    Views:
    3,805
    Mathieu Malaterre
    Aug 17, 2004
  5. Replies:
    2
    Views:
    555
    Mark P
    May 9, 2005
Loading...

Share This Page