KiXforms Forum Index KiXforms
The Forum for the KiXforms Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Quick Links 
Site News
Downloads
Documentation
Donations
Script Archive
Tracking Systems

memory leak with picture object

 
Post new topic   Reply to topic    KiXforms Forum Index -> Discussion
View previous topic :: View next topic  
Author Message
Bert
KiXforms Regular
KiXforms Regular


Joined: 06 Oct 2003
Posts: 56
Location: Netherlands

PostPosted: Sun Jan 11, 2004 2:56 pm    Post subject: memory leak with picture object Reply with quote

Shawn,

There seems to be a memoryleak with picture objects. When a pictureobject is destroyed the memory is not freed.
The following kixlet demonstrates this. You need a small .bmp file of 100*100 pixels in the script directory.

Start the script, compact your memory if there is no physical memory free, repeatedly press the 'test' button and watch the memory leak away.

Code:

   $Form = createobject ("kixtart.form")
   $form.width = 400
   $form.height = 400
   $Form.center
   test()
   $label = $form.label ("", 10, $picture.bottom + 10, 200, 15)
   $testbutton = $form.button ("Test")
   $testbutton.center
   $testbutton.top = $label.bottom+10
   $testbutton.onclick = "test()"

   $form.show
   while ($form.visible)
      $label.text = "Memorysize: "+MemorySize(1)
      $ = execute ($form.doevents())
   loop
   exit

function test ()
   if vartype ($picture) <> 0
      $picture.dispose
   endif
   $picture = $Form.controls.Picturebox ("", 150, 50, 100, 100)
   $picture.picture = "@SCRIPTDIR\test.bmp"
endfunction

_________________
Bert

There are 10 kinds of people. Those who can count binary and those who can't.
Back to top
View user's profile Send private message
Shawn
KiXforms Developer
KiXforms Developer


Joined: 22 Feb 2003
Posts: 1983
Location: Canada

PostPosted: Sun Jan 11, 2004 3:23 pm    Post subject: Reply with quote

Thanks, there sure is ... let me get right on it. Will definitely fix for the next release.
Back to top
View user's profile Send private message
Bert
KiXforms Regular
KiXforms Regular


Joined: 06 Oct 2003
Posts: 56
Location: Netherlands

PostPosted: Sun Jan 11, 2004 5:48 pm    Post subject: Reply with quote

The memoryleak is about 4 MB per test while the picture test.bmp is only 30KB.
_________________
Bert

There are 10 kinds of people. Those who can count binary and those who can't.
Back to top
View user's profile Send private message
Shawn
KiXforms Developer
KiXforms Developer


Joined: 22 Feb 2003
Posts: 1983
Location: Canada

PostPosted: Mon Jan 12, 2004 1:13 pm    Post subject: Reply with quote

Bert,

OK, I figured-out whats going on here. Its not a memory leak in the pure-pure sense of the term. What is actually happening is that the PictureBox controls are not being disposed of - they "think" they are still members of the Controls collection. To test this, try creating the PictureBoxes directly out of the Form object, and you will see that no memory is leaked, example:

$picture = $form.picturebox()

So what is happening in the code example above (using Controls) is that your new pictureboxes are actually sitting on top of the older ones, so you can't see them. If you were to create them with a small offset for the value of the Left property - you can see them start to pile-up.

But your right, it is leak in the sense that we can't gracefully dispose of the old controls. I have made the following design decision:

Since the control is created (added really) through the Controls collection, going forward - they must be Removed from the collection to be properly disposed of, so I added the following method in the next build:

$Form.Controls.Remove($Picture)

If one doesn't have a handle to a control, but knows its name. One can do this:

$Form.Controls.Remove($Form.Controls("Name"))

If I get a chance, will add the following method (but think I will time-out on this one) ... it will remove (clear) all the contros from the collection:

$Form.Controls.Clear

What you think ?

-Shawn
Back to top
View user's profile Send private message
Sealeopard
KiXforms Aficionado
KiXforms Aficionado


Joined: 05 Mar 2003
Posts: 436
Location: Boston, MA

PostPosted: Mon Jan 12, 2004 1:15 pm    Post subject: Reply with quote

The other interesting thing is that the picturebox is unable to display the picture after clicking the button multiple times (30+ times). The memory indicator decreases until it stops by which time the picturebox doesn't display the picture anymore. Tested with KiXforms v2.3.0.42.
_________________
Jens

'There are two kinds of vessels, submarines and targets.'
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Sealeopard
KiXforms Aficionado
KiXforms Aficionado


Joined: 05 Mar 2003
Posts: 436
Location: Boston, MA

PostPosted: Mon Jan 12, 2004 1:17 pm    Post subject: Reply with quote

Reading Shawns comment, my previous post now seems to indicate that there is a limit to the number of pictureboxes that can be created?
_________________
Jens

'There are two kinds of vessels, submarines and targets.'
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Shawn
KiXforms Developer
KiXforms Developer


Joined: 22 Feb 2003
Posts: 1983
Location: Canada

PostPosted: Mon Jan 12, 2004 1:33 pm    Post subject: Reply with quote

PictureBoxes are extremely taxing on system resources. A bitmap is allocated that is the size of the display monitor for each PictureBox you have (hence the 4mb thing) ... the reason the bitmap is so big is that one can not ony draw inside the borders of a picturebox, one can draw outside the "bounds" of a picturebox as well - and the drawing will be preserved.

For example, if you had a PictureBox that was 100x100, and you drew a circle at coord 500x500, then (say) using the Anchor property, stretched the picturebox size out to 600x600 - you would still see the circle you drew.

Looking back - I regret having made this decision. Should have just allocated a bitmap the size of the control - but then that raises other issues because everytime it was resized, a new bitmap would have to be allocated, copied and that would cause some flickering. If I had to do it again, would probably have gone the flickering route though. Pictureboxes aren't resized to often. On the other hand - Forms use the same method to preserve drawings and text - and they get resized often ...

I think in the long-term, I would want to move away from this huge bitmap allocation thingy. Maybe even to the point of someday correcting this situation. Certainly anything new won't use it.

-Shawn
Back to top
View user's profile Send private message
Shawn
KiXforms Developer
KiXforms Developer


Joined: 22 Feb 2003
Posts: 1983
Location: Canada

PostPosted: Mon Jan 12, 2004 5:51 pm    Post subject: Reply with quote

Just for your information. There is going to be (yet another) way to create controls in an upcomming release of Kixforms ... this new method won't be in the next release, or the one afterthat. But maybe in build 45 ...

I want to provide support for creating controls "off-screen", and then adding them into containers after they are configured. This is the approach that dotnet takes - its also implemented by JavaScript ... it will look something like this:

$Button = $System.Button()
$Button.Left = 100
$Button.Top = 100
$Button.Text = "Click Me"

$Form.Controls.Add($Button)

The benefit to this approach is that controls won't appear on the form right after construction. You can create and config them behind the scenes. This is especially important for things like GroupBoxes and TabControls, where the control contains many other controls. So for example to create a groupbox with a couple of buttons, then add them to the form in one go:

$GroupBox = $System.GroupBox()
$GroupBox.Location = 10,10

$Button1 = $System.Button()
$Button1.Location = 20,20

$Button2 = $System.Button()
$Button3.Location = 20,20

$GroupBox.Controls.Add($Button1)
$GroupBox.Controls.Add($Button2)
$Form.Controls.Add($GroupBox)

Of course, the old-style creation will continue to be supported. Just wanted to give a favor for some of the stuff in the works. This change I just did for Removing controls from the Controls collection is part of this framework I just laid-out.

-Shawn
Back to top
View user's profile Send private message
Bert
KiXforms Regular
KiXforms Regular


Joined: 06 Oct 2003
Posts: 56
Location: Netherlands

PostPosted: Mon Jan 12, 2004 8:50 pm    Post subject: Reply with quote

Shawn,

My demonstration kixlet was not the first one. I first created the picturebox out of the form directly and destroyed it with the =0 assignment. Then I found the 'memory leak'.
But because of the new way to create objects out of the controls collections I tested that too.
So I have this 'memory leak' both ways.
I tried to show hidden pictures by stacking new ones with an offset but that was not the case.

Code:

   dim $x, $y
   $x = 0 $y = 0
   $Form = createobject ("kixtart.form")
   $form.width = 400
   $form.height = 400
   $Form.center
   test()
   $label = $form.label ("", 10, $picture.bottom + 10, 200, 15)
   $testbutton = $form.button ("Test")
   $testbutton.center
   $testbutton.top = $label.bottom+10
   $testbutton.onclick = "test()"

   $form.show
   while ($form.visible)
      $label.text = "Memorysize: "+MemorySize(1)
      $ = execute ($form.doevents())
   loop
   exit

function test ()
   if vartype ($picture) <> 0
      $picture = 0
   endif
   $picture = $Form.Picturebox ("", $x, $y, 100, 100)
   $picture.picture = "@SCRIPTDIR\test.bmp"
   $x = $x + 5
   $y = $y + 5
endfunction


When you implement the removing by $form.controls.remove ($picture) we than have three ways to remove objects:
$object = 0
$object.dispose
$form.controls.remove ($object)

I still prefer one method: $object = 0
This will also work when a local variable containing an object is automatically destroyed when the containing function or gosub exits.

It might be handy to scan the container object for all objects and retrieve pointers and types. This could be used to clear all or selected objects in a loop.

About automatically hiding new objects. This was also on my whislist because of the flickering of pictures and labels with text in a big font in a different color (a label does appearently not inherit the forecolor of the form).
I thought of a new property like .hidenew = 1 that would do the trick. Creation of the object could be coded as usual and the last statement would be $object.show.

However I would also welcome the $system.object approach.

_________________
Bert

There are 10 kinds of people. Those who can count binary and those who can't.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    KiXforms Forum Index -> Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group