Re: Wx::Perl seems to be leaking memory
Hmm.., On 20/05/15 17:49, Steve Cookson - gmail wrote: If I create a few controls in a dialog, delete the dialog, use $app-Yield for the background processing to take place, I still end up with more Perl objects after the deletion than before. Well actually, although the count builds up for the first two calls. After the third call, although it says it's loosing 5 pointers per call, it is not, because the total number of pointers remains the same. So I suppose that is OK. I have switched off my background processing using Wx::Timer and all my memory creep stops. So unless you think the 5 pointers matter (and maybe it doesn't), I'm going to switch to looking at the Wx::Timer background code as potentially a more productive avenue. Thanks Steve.
Re: Wx::Perl seems to be leaking memory
Thanks for this. Actually, my timers run all the time in the background. On 21/05/15 10:54, Mark Dootson wrote: Just one other thing that may not be obvious unless you have read wxWidgets docs for wxTimer, Wx::Timer objects must be explicitly destroyed. e.g. $timer-Destroy; However, in the case of Wx::Timer the -Destroy call deletes the wxWidgets object immediatley. No point in you testing this out too much until I have fixed the Wx::TimerEvent SV leak problem. Mark On 21/05/2015 14:50, Mark Dootson wrote: Hi Steve, $app-Yield does not cause 'idle time' to happen - so 'Destroyed' objects are not cleaned up during that call. As you have seen, on multiple calls the total number of SVs does not increase so no memeroy leak there. However, in constructing an example to demonstrate this I think I may have found the cause of your issues. Every Wx::Timer event or call to an overridden 'Notify' method leaks 1 SV. I don't have a solution but will work on it over the weekend. Regards Mark On 21/05/2015 11:54, Steve Cookson wrote: Hmm.., On 20/05/15 17:49, Steve Cookson - gmail wrote: If I create a few controls in a dialog, delete the dialog, use $app-Yield for the background processing to take place, I still end up with more Perl objects after the deletion than before. Well actually, although the count builds up for the first two calls. After the third call, although it says it's loosing 5 pointers per call, it is not, because the total number of pointers remains the same. So I suppose that is OK. I have switched off my background processing using Wx::Timer and all my memory creep stops. So unless you think the 5 pointers matter (and maybe it doesn't), I'm going to switch to looking at the Wx::Timer background code as potentially a more productive avenue. Thanks Steve.
Re: Wx::Perl seems to be leaking memory
Hi Steve, $app-Yield does not cause 'idle time' to happen - so 'Destroyed' objects are not cleaned up during that call. As you have seen, on multiple calls the total number of SVs does not increase so no memeroy leak there. However, in constructing an example to demonstrate this I think I may have found the cause of your issues. Every Wx::Timer event or call to an overridden 'Notify' method leaks 1 SV. I don't have a solution but will work on it over the weekend. Regards Mark On 21/05/2015 11:54, Steve Cookson wrote: Hmm.., On 20/05/15 17:49, Steve Cookson - gmail wrote: If I create a few controls in a dialog, delete the dialog, use $app-Yield for the background processing to take place, I still end up with more Perl objects after the deletion than before. Well actually, although the count builds up for the first two calls. After the third call, although it says it's loosing 5 pointers per call, it is not, because the total number of pointers remains the same. So I suppose that is OK. I have switched off my background processing using Wx::Timer and all my memory creep stops. So unless you think the 5 pointers matter (and maybe it doesn't), I'm going to switch to looking at the Wx::Timer background code as potentially a more productive avenue. Thanks Steve.
Re: Wx::Perl seems to be leaking memory
On 14/05/15 15:24, Steve Cookson wrote: That has been a very painful lesson. We've now run over 60 video tests with no crashes, so I hope it is resolved. I spoke too soon: the crashes have just moved to a different part of the system. I've cut down a piece of code to try to isolate the problem and it follows this email. If I create a few controls in a dialog, delete the dialog, use $app-Yield for the background processing to take place, I still end up with more Perl objects after the deletion than before. Any ideas welcome. Regards Steve #! /usr/bin/perl package main; use strict; use warnings; $main::app = App-new(); $main::app-MainLoop; package App; use strict; use warnings; use base 'Wx::App'; sub OnInit { Wx::InitAllImageHandlers(); my $frame = Launch-new(); $frame-Show(1); } package Launch; use strict; use warnings; use Wx qw(:everything); use base qw(Wx::Frame); use Devel::Leak; sub new { my ($class, $parent) = @_; my $i_frame = $class-SUPER::new($parent, -1, Test, wxDefaultPosition, wxDefaultSize); $i_frame-{panel} = Wx::Panel-new($i_frame, -1, wxDefaultPosition, wxDefaultSize); $i_frame-{sizer} = Wx::BoxSizer-new(wxVERTICAL); $i_frame-{button} = Wx::Button-new($i_frame-{panel}, -1, Launch, wxDefaultPosition, wxDefaultSize); $i_frame-{sizer}-Add($i_frame-{button}); $i_frame-{panel}-SetSizer($i_frame-{sizer}); $i_frame-{panel}-Layout(); Wx::Event::EVT_BUTTON( $i_frame, $i_frame-{button}, sub { my ($self1, $event1) = @_; my $count1 = Devel::Leak::NoteSV(my $handle); my $frame = Dialog-new(); $frame-ShowModal(); $frame-Destroy(); $main::app-Yield(); my $count2 = Devel::Leak::CheckSV($handle ); print $count1, \n; print $count2, \n; print $count2-$count1, \n; }); return $i_frame; } package Dialog; use strict; use warnings; use Wx qw(:everything); use base qw(Wx::Dialog); sub new { my ($class, $parent) = @_; my $frame2 = $class-SUPER::new($parent, -1, Test i_Layout , wxDefaultPosition, wxDefaultSize); $frame2-{panel2} = Wx::Panel-new($frame2, -1 , wxDefaultPosition, wxDefaultSize, ); $frame2-{sizer2} = Wx::BoxSizer-new(wxHORIZONTAL); $frame2-{panel2}-SetSizer($frame2-{sizer2}); $frame2-{panel2}-Layout(); return $frame2; } 1;
Re: Wx::Perl seems to be leaking memory
Hi Guys (and Mark in particular), That has been a very painful lesson. We've now run over 60 video tests with no crashes, so I hope it is resolved. When something in a completely different part of the system starts to crash, it's easy not to think 'memory'. And in fact I've put all sorts of fixes around threading, callbacks, wxTimer, v4l2 drivers, some of which appeared to work and then mysteriously stopped working. So thanks Mark. I'm very grateful for your help. Steve. On 11/05/15 15:58, Mark Dootson wrote: Hi, A top level window is a Wx::Frame or a Wx::Dialog - or any class that derives from them. You can find which built in classes are top level windows from http://docs.wxwidgets.org/3.0/classwx_top_level_window.html You don'thave to explicitly destroy children ( controls ) of your top level windows. A Wx::Panel is just a type of control - not a top level window. Note that if you choose to make them so in their contstructors, top level windows can be children of other top level windows. In which case, destroying the parent will destroy all children too. An approach that can be used in an application with many Wx::Frames is to add an EVT_CLOSE handler to your Wx::Frame derived class and have the frame call $self-Destroy in your EVT_CLOSE handler. That way whenever a frame is closed, it will be properly deleted during idle time. Hope it helps. Mark On 11/05/2015 17:05, Steve Cookson wrote: Hi Mark, Thanks for this. So the short answer was that I had indeed made a fundamental error. I should update PM. Maybe I knew all this once upon a time, but I had definitely forgotten it long since!! It explains why I had leaks all over the place. Some of which must have been quite big because of embedded scrolling photos and other stuff. Can I just clarify what is meant by toplevel. I guess it means anything that groups controls that you would normally expect to disapear because of going out of scope: any Dialog, Panel or Frame with children or indeed a tree of descendants. Or does it just mean the application main frame? And if a whole tree goes out of scope simultaneously, eg controls in sizers on panels within panels in a dialog, is it enough to Destroy the dialog? Thanks again, Regards, Steve. On 11/05/15 11:52, Mark Dootson wrote: Hi, See http://docs.wxwidgets.org/3.0/classwx_window.html#a6bf0c5be864544d9ce0560087667b7fc details for wxWindow::Destroy. As you have determined, top level windows you create need to be destroyed with $win-Destroy; The C++ structure for a Wx::Frame contains a reference to the associated Perl SV. So that SV won't go away until the C++ structure is deleted - which will never happen until your event loop is running. Hope this helps. Mark On 11/05/2015 14:32, Steve Cookson wrote: Hi Guys, I started to talk about this on Perl Monks, you may have seen it here: http://www.perlmonks.org/?node_id=1125580 An anonymous monk posted some code that showed just about every call to Wx leaking a scalar or two. I've played about with the posted code and there is a copy attached to this email. The main part of the code, here: $count1 = Devel::Leak::NoteSV($handle); for(1..100){ my $f=Wx::Frame-new( undef ,-1,goner ); my $p=Wx::Panel-new (undef ,-1 ); #my $b=Wx::Button-new ( $f ,-1 ); #my $t=Wx::TextCtrl-new($f, -1, ); #$t-Destroy; #$b-Destroy; #$i-Destroy; $p-Destroy; $f-Destroy; } $count2 = Devel::Leak::CheckSV($handle); seems to show that if you do not -Destroy a Wx object, it will not go out of scope naturally and even if you do destroy a Wx::Frame object, it will not go out of scope. The monk also tried Weaken and undef, with the same results. Please have a look at this and make sure that I have not (or the Anonymous Monk has not), made some fundamental error. I have checked it both in 2.8.11 and 3.0.2 with the same results. I look forward to hearing your feedback, Regards Steve.
Re: Wx::Perl seems to be leaking memory
Hi, See http://docs.wxwidgets.org/3.0/classwx_window.html#a6bf0c5be864544d9ce0560087667b7fc details for wxWindow::Destroy. As you have determined, top level windows you create need to be destroyed with $win-Destroy; The C++ structure for a Wx::Frame contains a reference to the associated Perl SV. So that SV won't go away until the C++ structure is deleted - which will never happen until your event loop is running. Hope this helps. Mark On 11/05/2015 14:32, Steve Cookson wrote: Hi Guys, I started to talk about this on Perl Monks, you may have seen it here: http://www.perlmonks.org/?node_id=1125580 An anonymous monk posted some code that showed just about every call to Wx leaking a scalar or two. I've played about with the posted code and there is a copy attached to this email. The main part of the code, here: $count1 = Devel::Leak::NoteSV($handle); for(1..100){ my $f=Wx::Frame-new( undef ,-1,goner ); my $p=Wx::Panel-new (undef ,-1 ); #my $b=Wx::Button-new ( $f ,-1 ); #my $t=Wx::TextCtrl-new($f, -1, ); #$t-Destroy; #$b-Destroy; #$i-Destroy; $p-Destroy; $f-Destroy; } $count2 = Devel::Leak::CheckSV($handle); seems to show that if you do not -Destroy a Wx object, it will not go out of scope naturally and even if you do destroy a Wx::Frame object, it will not go out of scope. The monk also tried Weaken and undef, with the same results. Please have a look at this and make sure that I have not (or the Anonymous Monk has not), made some fundamental error. I have checked it both in 2.8.11 and 3.0.2 with the same results. I look forward to hearing your feedback, Regards Steve.
Re: Wx::Perl seems to be leaking memory
Hi, A top level window is a Wx::Frame or a Wx::Dialog - or any class that derives from them. You can find which built in classes are top level windows from http://docs.wxwidgets.org/3.0/classwx_top_level_window.html You don'thave to explicitly destroy children ( controls ) of your top level windows. A Wx::Panel is just a type of control - not a top level window. Note that if you choose to make them so in their contstructors, top level windows can be children of other top level windows. In which case, destroying the parent will destroy all children too. An approach that can be used in an application with many Wx::Frames is to add an EVT_CLOSE handler to your Wx::Frame derived class and have the frame call $self-Destroy in your EVT_CLOSE handler. That way whenever a frame is closed, it will be properly deleted during idle time. Hope it helps. Mark On 11/05/2015 17:05, Steve Cookson wrote: Hi Mark, Thanks for this. So the short answer was that I had indeed made a fundamental error. I should update PM. Maybe I knew all this once upon a time, but I had definitely forgotten it long since!! It explains why I had leaks all over the place. Some of which must have been quite big because of embedded scrolling photos and other stuff. Can I just clarify what is meant by toplevel. I guess it means anything that groups controls that you would normally expect to disapear because of going out of scope: any Dialog, Panel or Frame with children or indeed a tree of descendants. Or does it just mean the application main frame? And if a whole tree goes out of scope simultaneously, eg controls in sizers on panels within panels in a dialog, is it enough to Destroy the dialog? Thanks again, Regards, Steve. On 11/05/15 11:52, Mark Dootson wrote: Hi, See http://docs.wxwidgets.org/3.0/classwx_window.html#a6bf0c5be864544d9ce0560087667b7fc details for wxWindow::Destroy. As you have determined, top level windows you create need to be destroyed with $win-Destroy; The C++ structure for a Wx::Frame contains a reference to the associated Perl SV. So that SV won't go away until the C++ structure is deleted - which will never happen until your event loop is running. Hope this helps. Mark On 11/05/2015 14:32, Steve Cookson wrote: Hi Guys, I started to talk about this on Perl Monks, you may have seen it here: http://www.perlmonks.org/?node_id=1125580 An anonymous monk posted some code that showed just about every call to Wx leaking a scalar or two. I've played about with the posted code and there is a copy attached to this email. The main part of the code, here: $count1 = Devel::Leak::NoteSV($handle); for(1..100){ my $f=Wx::Frame-new( undef ,-1,goner ); my $p=Wx::Panel-new (undef ,-1 ); #my $b=Wx::Button-new ( $f ,-1 ); #my $t=Wx::TextCtrl-new($f, -1, ); #$t-Destroy; #$b-Destroy; #$i-Destroy; $p-Destroy; $f-Destroy; } $count2 = Devel::Leak::CheckSV($handle); seems to show that if you do not -Destroy a Wx object, it will not go out of scope naturally and even if you do destroy a Wx::Frame object, it will not go out of scope. The monk also tried Weaken and undef, with the same results. Please have a look at this and make sure that I have not (or the Anonymous Monk has not), made some fundamental error. I have checked it both in 2.8.11 and 3.0.2 with the same results. I look forward to hearing your feedback, Regards Steve.
Re: Wx::Perl seems to be leaking memory
Hi Mark, Thanks for this. So the short answer was that I had indeed made a fundamental error. I should update PM. Maybe I knew all this once upon a time, but I had definitely forgotten it long since!! It explains why I had leaks all over the place. Some of which must have been quite big because of embedded scrolling photos and other stuff. Can I just clarify what is meant by toplevel. I guess it means anything that groups controls that you would normally expect to disapear because of going out of scope: any Dialog, Panel or Frame with children or indeed a tree of descendants. Or does it just mean the application main frame? And if a whole tree goes out of scope simultaneously, eg controls in sizers on panels within panels in a dialog, is it enough to Destroy the dialog? Thanks again, Regards, Steve. On 11/05/15 11:52, Mark Dootson wrote: Hi, See http://docs.wxwidgets.org/3.0/classwx_window.html#a6bf0c5be864544d9ce0560087667b7fc details for wxWindow::Destroy. As you have determined, top level windows you create need to be destroyed with $win-Destroy; The C++ structure for a Wx::Frame contains a reference to the associated Perl SV. So that SV won't go away until the C++ structure is deleted - which will never happen until your event loop is running. Hope this helps. Mark On 11/05/2015 14:32, Steve Cookson wrote: Hi Guys, I started to talk about this on Perl Monks, you may have seen it here: http://www.perlmonks.org/?node_id=1125580 An anonymous monk posted some code that showed just about every call to Wx leaking a scalar or two. I've played about with the posted code and there is a copy attached to this email. The main part of the code, here: $count1 = Devel::Leak::NoteSV($handle); for(1..100){ my $f=Wx::Frame-new( undef ,-1,goner ); my $p=Wx::Panel-new (undef ,-1 ); #my $b=Wx::Button-new ( $f ,-1 ); #my $t=Wx::TextCtrl-new($f, -1, ); #$t-Destroy; #$b-Destroy; #$i-Destroy; $p-Destroy; $f-Destroy; } $count2 = Devel::Leak::CheckSV($handle); seems to show that if you do not -Destroy a Wx object, it will not go out of scope naturally and even if you do destroy a Wx::Frame object, it will not go out of scope. The monk also tried Weaken and undef, with the same results. Please have a look at this and make sure that I have not (or the Anonymous Monk has not), made some fundamental error. I have checked it both in 2.8.11 and 3.0.2 with the same results. I look forward to hearing your feedback, Regards Steve.