Windows Handle Question

Hey all,

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…

Won’t make a difference.

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.

Even pictures have handles. It’d be unsurprising that the issue is because pictures aren’t freed (or less frequently than expected).

So to answer everyone:

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…

Are you using the latest version? 23r1.1 ?

Can you create a sample isolating a window creating such leakage so Xojo could track the issue?

That’s the problem. I have one window where things seem to work fine and another where it leaks. So creating a test project might not show anything…

And Xojo wouldn’t be able to test it anyhow as they don’t have the hardware to interface to that is sending me the bit streams…

Create a sample removing all things but preserving that specific problematic 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.

Does this function load a picture each time?

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.

Not necessarily, but that method is not used when I am receiving the bitmap data. So it has no effect here.

Is there a way to force the framework to release an image or something like that. It seems like garbage collection is not happening quickly enough…

That’s possible but it would take quite a bit of work to get things to that point…

In general you should never ever run out of Windows handles unless there is serious handle leak in the application.

2 Likes

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.

This is system wide, per process is half of it.