Genii Weblog

Tracking memory leaks with Lsi_info

Tue 27 Apr 2004, 02:45 PM



by Ben Langhinrichs
While it is not a well kept secret, the undocumented Lsi_info function in LotusScript has secrets within secrets.  There is actually a file called LSPRCVAL.LSS in your Notes directory which lists a number of constants for Lsi_info (see the bottom of this post for the 6.0.2 version), but besides these documented constants for the undocumented function, there are undocumented constants.  I am going to concentrate on three that help significantly when tracking memory loss.  This is an issue that is near and dear to my heart since I develop C/C++ extensions and LSXs, and while this may shock you, sometimes memory leaks.   Eeek!  These functions are very helpful when testing our Midas Rich Text LSX, as well as other LSXs, to ensure that memory is not leaking, but even for non-API developers, these are very helpful for determining whether Notes is not letting go of memory for one reason or another.

"So", some bright soul is sure to say, "aren't these just the constants for GetThreadInfo?"

Well, yes they are, but Lsi_info allows values that GetThreadInfo doesn't, and also works in any previous version of Notes, which GetThreadInfo doesn't either.  For these reasons, I use the Lsi_info function.

My agent
The simple agent I tend to use is below saves the agent name and three values:

LSI_Info(50) returns the LotusScript memory allocated. 
LSI_Info(51) returns the LotusScript memory allocated from the OS. 
LSI_Info(52) returns the LotusScript blocks used. 

Sub Initialize
   DimAs New NotesSession
   Dim agent As NotesAgent
   Dim db As NotesDatabase
   Dim doc As NotesDocument
   
   Set db=s.CurrentDatabase
   Set agent = s.CurrentAgent
   Set doc = New NotesDocument(db)
   doc.Form = "MemoryLog"
   doc.AgentName = agent.Name
   doc.lsMemory = Lsi_info(50)
   doc.lsMemoryOS = Lsi_info(51)
   doc.lsMemoryBlks = Lsi_info(52)
   Call doc.Save(True, True)
End Sub

My agent simply saves a document with the current values each time it is called.  You could log this instead, or simply compare one to another, but be aware that there is a lot of start up cost to some operations, and there is also a cost to any background processes running, so try this when nothing else is happening and when you control the situation as much as possible.  With LSX issues, or API issues called through LotusScript, the most important number is usually the blocks.  These represent the "handles" used to open a document or allocate a block of memory, and if this value keeps growing, you will eventually die.  The LotusScript memory tends to grow more with pure LotusScript use, and the memory allocated from the OS tells you whether you are taxing the external memory.  

My best advice is, don't sweat the details.  If any of these values keeps growing, you probably have a problem.  If the number of blocks keeps growing, make sure to do explicit deletes of objects and see if that helps.  If the blocks stay the same and memory keeps growing, watch for arrays and lists that are growing uncontrollably.

Additional undocumented codes
LSI_Info(12) Procedure name of call to current procedure (according to this post by Damien Masson)

LSI_Info(14) returns a list of the LS modules called so far. There are three parameters for each module. The first seems to be some code for the script library, the second is the module name, and the third is the last line number executed in the module before the net module was called (according to this post by Peter Presnell)

Documented codes from LSPRCVAL.LSS file
'-----------------------------------------------------------------------------
' File:      lsprcval.lss
' Copyright (c) 1997 Lotus Development Corporation
'
' Description:  Constants for use with the LSITHREADINFO builtin
'
'-----------------------------------------------------------------------------
public const LSI_THREAD_LINE=0
public const LSI_THREAD_PROC=1
public const LSI_THREAD_MODULE=2
public const LSI_THREAD_VERSION=3
public const LSI_THREAD_LANGUAGE=4
public const LSI_THREAD_COUNTRY=5
public const LSI_THREAD_TICKS=6
public const LSI_THREAD_TICKS_PER_SEC=7
public const LSI_THREAD_PROCESS_ID=8
public const LSI_THREAD_TASK_ID=9
public const LSI_THREAD_CALLPROC=10
public const LSI_THREAD_CALLMODULE=11

Copyright © 2004 Genii Software Ltd.

What has been said:


150.1. Alain H Romedenne
(01/18/2005 01:14 AM)

Hi Ben,

public const LSI_INFO_TICKS=99

public const LSI_INFO_TICKS_PER_SEC=98

I have used these while developing a x-releases, x-platforms of NotesStopwatch LotusScript timer that is packaged within OpenDOM project at OpenNTF.

;-)


150.2. rohit
(04/19/2005 01:33 AM)

hi, it's really good!!

One more thing i wana know that can we write lotus script functions out side in file and then include in options like other .lss files.


150.3. megan
(04/09/2006 09:33)

hey dom its megan really trying hard to get in contaact with you as i aint spoke to u 4 ages. have something really important to tell you but i don't know if you are off travelling yet so won't tell you over the e-mail. if u r still around can u e-mail me at rileytaite@hotmail.com with ur number as its really important.

thanks megan