I’m seeing an issue in my app where in one of my windows after doing some continual updates of some canvases for a period of time, I get the following exception error:
The current process has used all of its system allowance of handles for Window Manager Objects
This is stumping me because I have another window where I am doing pretty much the same sort of actions and that works no problem. Basically the app is being sent a bitmap of an image, I am converting this bitmap to a picture and then updating one or more canvases. This happens at a rate of maybe 10 times a second maximum. And the number of canvases being updated can vary. In the case of the “failing” window, I have something like 14 canvases. On the window where I don’t have the failure, I can have more.
And what’s odd is that on the window where I’m having an issue, the canvases are pretty small at 115x65. On the other window, the canvases are much larger.
I’m not keeping multiple copies of these imported images in storage or holding references to them. I create the picture in the method called when I receive the bit map. That picture is then stored in a picture property of the window. Then I refresh the canvas and the canvas draws the picture.
Any idea what this issue could be? It’s almost like some trash collection is not running fast enough in the framework and things build up…
Pretty much if not every every rectangular object on screen (button, window, listbox…) has a ‘window handle’… a unique ID so that it can send and receive messages.
The message means ‘no more unique numbers are being issued’
Are you creating controls on the fly anywhere in your code?
Are you creating new timers anywhere in your code?
Do you create a new window every time you update the screen?
Are you using any of the newer graphics methods introduced in Xojo over the last year or two?
Are you using declares? Maybe causing issues on Xojo’s control on the lock/release handle system? Are you sure you are releasing everything you temporally used? Are you abusing on the creating objects? The max is around 10k per process and 32k FOR ALL, for everything running in your computer at that time. If you have LOTS of things open, your app can be collaterally affected. The last thing is that you could be affected by some Xojo bug fired by some condition you found.
1.) I’m creating controls dynamically when the window is built. But nothing when painting the pictures.
2.) There’s no timers being created with the exception that the DataAvailable event of the TCP socket that receives the image data fires a timer.
3.) New window is not being created.
4.) Not using declares
5.) Not using any of the newer graphics methods. Primarily I am still running API 1.0. Controls are all “original” and not the new “desktop” controls.
I think @Arnaud_N is correct. However, I can’t understand why the second window I have where I do pretty much a similar thing doesn’t have this issue. You would think all windows would behave similarly…
One more tidbit (sometimes but not always), the app starts eating memory - very, very slowly at first but then it takes off exponentially.
If I bypass the paint event (ie: I just don’t call a refresh), I can take and receive/format the picture data and all no problem. So it’s something going on due to painting the picture or something happening in the window after that…
Here’s the code in my canvas paint event. If I’m not receiving this pseudo-live image data,I show an icon. If I am capturing image data is where I have the problem. CapturePic is the captured image that has been sent to me and that I have processed.
#If TargetWindows Then
If CapturePic = Nil Then
Me.DoubleBuffer = False
Me.EraseBackground = True
Else
Me.DoubleBuffer = True
Me.EraseBackground = False
End If
#EndIf
Dim p as Picture
Dim DrawRect as Boolean
If Not UseCaptureForIcon Or CapturePic = Nil Then
DrawRect = False
If SourceChanged Then
IconPic = LoadIconPic
End If
p = IconPic
Else
DrawRect = True
p = CapturePic
End If
If SourceChanged Then
SourceChanged = False
End If
If p <> Nil Then
Dim Aspect As Double = p.Width/p.Height
Dim pleft As Integer = (Me.Width-Me.height*Aspect)\2
g.DrawPicture(p,pleft,0,me.height*Aspect,me.height,0,0,p.Width,p.Height)
g.ForeColor=&c00000000
g.PenHeight=3
g.DrawRect(0,0,g.Width,g.Height)
End if
RaiseEvent Paint(g,areas)
In the container control where the canvases are all built, I have the following code in the paint event. JAPRX (it’s a custom object but is stored in the canvas as a weak-ref) is a real-world device that is sending me the image data. If we are connected to it I’m drawing a small green dot in the lower left of the canvas. If disconnected, it’s red.
If Me.JAPRX <> Nil And UseL3 And Me.JAPRX.IPAddress <> "" Then
Dim o as New OvalShape
o.Width = 6
o.Height = 6
o.X = 3
o.Y = me.Height-3
o.BorderWidth = 0.25
o.Border = 100
If me.JAPRX.AttemptingLogin Then
o.BorderColor = &cE4CE1F00 '&cFFD00000
o.FillColor = &cFFFF0000
ElseIf me.JAPRX.Connected Then
o.BorderColor = &c00800000
o.FillColor = &c00FF0000
Else
o.BorderColor = &c80000000
o.FillColor = &cFF000000
End If
g.DrawObject o
End If
I have no other paint event calls in the container control that has these canvases or the parent window…
Don’t do that, simulate. A sample does not equal to real world. A hardware creates a “pulse with some values” you create a timer “pulsing some values” instead. Simulate basic conditions to trigger the problem.
I’ve run into a similar situation as you, years ago. I was drawing screenshots directly into a graphics context but didn’t released the context’s handle. So each time I was drawing, one more handle was created, until the API complained (and the app crashed, IIRC, in my case).
Your issue sounds close to mine, but I fail to see what would create pictures (or contexts) in your app, that would be unusual in Xojo.
It’s not a matter of time, though. The handles’ count limit, it’s a fixed number (I don’t recall how much, say… 512); you may reach this number sooner or later, just because of the number of created and unreleased objects grows.
In general, this happens because of using non-Xojo methods (i.e. plugins or declares, or possibly shell calls). Do you use any of these?
The handles that count toward it are in general mostly handles that your not supposed to keep for long time like GDI handles, Pens, Brushes, etc. else obviously all those massive Windows applications out there like Visual Studio for example obviously constantly hit the limit. The limit is 32k handles.
So no you will not hit the roof of this just by adding normal things in the application without having massive handle leak.