RobotStudio event

How stop memory leaking? Increase Virtual Memory?

Options
Hello,
 

I have made an RAB application in VS2005 - VB.  I am using RW 5.12.0 and have a lot of problems keeping my Flexpendant application running.

 

The compiled size of my Flexpendant program (TpsViewScreen.dll) = 1.5 Mb.

 

The problems is that there is a (big) memory leak. When the Flexpendant is restarted then the first time then the default user is active. When a different user is logging in and my application is reloaded I already get the message: Out of virtual memory.

 

I used the command GC.GetTotalMemory(False).ToString to display the amount of memory used on the screen.

When the FP is new started and the mainscreen of my application is displayed the memory used is: 1.55 Mb.  I have 5 different subScreens and after the subscreens have been opened the used memory is increased to 1.7 Mb (=van be normal I suppose).

 

I programmed a Dispose handler for each subscreen and one for the Mainscreen.

It seems that the Dispose Handlers of the subscreens are NOT called. => Memory is not released.

Questions:

- What must I do to call this Dispose handlers?

- Should this be done automaticly?

- How can I check if the disposing is done?

 

If the memory used is over 1.8Mb the Flexpendant is restarting because it is Out of Virtual Memory.

Questions:

- Is it possible to increase the amount of VirtualMemory which can be used?

- If Yes, How?

 

In my subscreen I programmed a flag for remembering that the screen has been opened.

In the  Uninstall() handler of my application I reopen the screens which where opened before and dispose the data of my subscreen on the following way:

 

In my Mainscreen:

 

Sub Uninstall() Implements ITpsView.Uninstall

   IF bDisposeSubScreen1 THEN

      bDisposeData = True

      tffrmSubScreen1.ShowMe(Me) 

   EndIf


   IF bDisposeSubScreen2 THEN

      bDisposeData = True

      tffrmSubScreen2.ShowMe(Me) 

   EndIf
   IF bDisposeSubScreen3 THEN

      bDisposeData = True

      tffrmSubScreen3.ShowMe(Me) 

   EndIf
   IF bDisposeSubScreen4 THEN

      bDisposeData = True

      tffrmSubScreen4.ShowMe(Me) 

   EndIf
   IF bDisposeSubScreen5 THEN

      bDisposeData = True

      tffrmSubScreen5.ShowMe(Me) 

   EndIf

EndSub

In my SubScreens:

 

Private sub My_Base_Load(... ) Handles MyBase.Load

  bDisposeSubScreenX = TRUE

  If bDisposeData=TRUE THEN

    Me.Dispose(TRUE)

    Me.CloseMe()

  EndIf

End Sub

 

Now it seems that the memory is released because the dispose handler of my subscreen is called. The problem is that I have 5 subscreens. Only 1 or 2 subscreens will be handled, even when I call all the 5 sub screens for disposing.

 

Questions:

- Is there a time limitation for using the Deactivate() and Uninstall() handlers?

- How can I call a dispose handler in a subscreen in a good way? Please give a working 

  example.

 

 

Thanks already.

 

MD

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Comments

  • RussD
    Options
    What about all of the Controller, RapidData, IOSignal, etc. instances that your application creates, are you explicitly disposing of them as well? Just disposing of the container does not clean up these FPSDK components. You should follow the memory management guidelines in the User's Guide and use the console output to profile yor memory usage.
    Russell Drown
  • CSI_MD
    Options

    I am disposing everything what I am not using anymore directly:

    For all the IO I use I do in the MainScreen :

     

    doMyOutput = AController.IOSystem.GetSignal("doMyOutPut")

    AController.IOSystem.GetSignal("doMyOutPut").Dispose()

     

     

    For all RapidData I do in the MainScreen:

     

    rbt_rdRapidData = AController.Rapid.GetTask("MAINTASK").GetModule("GLOBAL").GetRapidData("RapidData")


    rbt_rdtRapidData 0 AController.Rapid.GetTask("MAINTASK").GetModule("GLOBAL").GetRapidData("RapidData").DataType

    rbt_RapidData = New tRapidData(rbt_rbtRapidData)

    AController.Rapid.GetTask("MAINTASK").Dispose()

    AController.Rapid.GetTask("MAINTASK").GetModule("GLOBAL").Dispose()AController.Rapid.GetTask("MAINTASK").GetModule("GLOBAL").GetRapidData("RapidData").Dispose()

    AController.Rapid.GetTask("MAINTASK").GetModule("GLOBAL").GetRapidData("RapidData").DataType.Dispose()

     

     

     

     

     

     
  • RussD
    Options

    I think you may be creating new references to data when you call GetSignal, GetTask, GetModule, etc. For instance, why not just do:


    Dim doMyOutput as Signal

     

    Try

      doMyOutput = AController.IOSystem.GetSignal("doMyOutPut")

      'do something with the value

      ...

      ...

    Catch

      'handle exceptions

    Finally

      If not doMyOutput is nothing then

        doMyOutput. Dispose

        doMyOutput = nothing

      End If

      'dispose of any other local declarations

    End Try

     

     
    Russell Drown
  • carlosmtz2000
    Options

    Some quick questions:

    - Why are you opening windows in the uninstall?

    - Are you opening the windows "on demand", or are they opened all the time?

     

    When the FP is closing an application, most of the controls inside the Main screen will be disposed (all TpsControls and TpsForms). Since we are closing and disposing the main screen, all child screens will be also closed (as long as they are opened, which means that they belong to the main screen).

     

    Why is your DLL so big? .. do you have images?

     

    Thanks
    Carlos Martinez
    ABB
  • CSI_MD
    Options

    RussD,
     

    The only time when the data is called is when starting the application. So I think I do not create new references everytime. I will try what you propose but I think this is not the problem.

     

    Carlos,

     

    You are right by asking these questions because it looks very silly. I am struggeling for days already to get rid of the memory consumption.

    I made some tests and I think the Dispose handlers from my Child tasks are not called when the application is closed using the red cross on the upper right corner. When I normally close a Child task , using Me.CloseMe() , then I can see that the used items in the child task remain in the memory.  I used the command Me.Dispose(true) (this calls the Dispose Handler of my Child task) just before closing the Child Task and I saw that the memory was released. The problem is that when you open the same Child Task again, I get  Object IsDisposed exeptions because it can not find my objects again.

     

    My Idea was:

    - Remember if and which child task has been opened before.

    - When closing the main application => Uninstall is called.

    - In the Uninstall I reopen the used Child Task and Dispose everything using Me.Dispose(true)

      The data is not longer used then, so I wont get the IsDisposed exeptions.

     

    I have 5 sub screens. I put a GTPUMessageBox in every subscreen just before disposing the data. When I close my application I am expecting 5x a message that the data of each sub screen is Disposed.  The problem is that only one or two of the sub screens give a message. So I think the memory leaks I have are because the data of the subscreens are not disposed.

    I tried both with Deactivate() and UnInstall(). They both react the same.

     

    Maybe I say stupid things now, but I think there is a time limit of using the Deactivate() and Uninstall() routines. It is very unpredictable what is called or not.

     

    I have also seen that when the used memory is over 1.8Mb that a subscreen is not loaded at all when I try to open. No error message appears, but I know at that moment that the Flexpendant will restart without warning from it self very soon.

     

     

    I am only opening other windows on demand.

     

     

     

    The reason why my dlls are so big is yet under investigation. My application before was almost 6Mb but in this version I used some .BMP files. The bitmaps I converted to .JPG.

    By the way I used             1 JPG  : 102k

                      I used about 10 GIFs : totally about 50k

    I have other applications build the same for other customers and these are about 400k.

    I do not now yet why this application is so big. This is my first application using RW5.12 but I dont think this is the reason. I compiled the same application using 5.11 and the result is the same.

     

    Thanks so far

     

    MD

     

     

     

     

     

     

     

     
  • carlosmtz2000
    Options
    Hi,
     

    There are no stupid things .. only desesperate approaches :)  ...

     

    Some quick notes:

     

    - Every time you open a child screen, you create a new instance (New MyForm) and connect to its Closed event. In the Closed event, you dispose the instance. In case you are holding a reference to the child screen, set this reference to null, so the next time you are opening the same screen, you will create a new one

     

    - GTPUMessageBox does not reacts similar as MessageBox. The main difference is that GTPYMsgBox does not stop the program execution (you problaly now this :)  ... ). In case you want to see if your disposed are called, I would recommend to use a regular MessageBox. Please not that MessageBox are not recommended for the whole FlexPendant, since all the FlexPendant will wait until that MessageBox closes. But at least it will help you to debug.

    - If you are still struggling, please feel free to send your application through email (so it is not published here).

     

    Kind Regards ...
    Carlos Martinez
    ABB