Overview
So we use QuickFixN within some production code. We have observed that over a period of 4-5 days the memory footprint of our app grows up to around 2GB.
We profiled the app, and can see that the cause appears to be FileStore where the offsets_ Dictionary is storing too much data

One thing to note, is that left alone, our app rarely restarts
I have downloaded the QuickFixN code and been digging about to see where the offsets_ is used and how it is cleared, and the following is what I see
FileStore
The FileStore class contains the offsets_ which is only cleared, when the ConstructFromFileCache() method is called. Which in turn is called when the FileStore.open() method is called, which is only called under 2 conditions
FileStore construction
Reset() called on FileStore
So I was thinking perhaps the Reset needs to be called. But by whom and when?
SessionState
So I dug some more, and can see that the FileStore.Reset() is called from SessionState.Reset(string reason). Which in turn is called by various other call sites from Session.
Session
- The calls to
SessionState.Reset() looks like an integral part of the QuickFixN implementation, so these call sites are obviously correct and tested by this repo. Basically I trust the existing Session calls to to SessionState.Reset()
So the question
Is this memory footprint normal, or is specific QuickFixN application code expected to also call the Session.Reset() which will call the callsites I mention above? Where the end result could be a call to the FileStore.ConstructFromFileCache.
However looking into this, I am not sure a Reset would work, as from what I can tell the FileStore.ConstructFromFileCache() method would read the contents of the files shown in image below to construct the offsets_. Which is obviously will just fill the offsets_ straight back up.
private void ConstructFromFileCache()
{
offsets_.Clear();
if (System.IO.File.Exists(headerFileName_))
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(headerFileName_))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string[] headerParts = line.Split(',');
if (headerParts.Length == 3)
{
offsets_[Convert.ToInt32(headerParts[0])] = new MsgDef(
Convert.ToInt64(headerParts[1]), Convert.ToInt32(headerParts[2]));
}
}
}
}
if (System.IO.File.Exists(seqNumsFileName_))
{
using (System.IO.StreamReader seqNumReader = new System.IO.StreamReader(seqNumsFileName_))
{
string[] parts = seqNumReader.ReadToEnd().Split(':');
if (parts.Length == 2)
{
cache_.SetNextSenderMsgSeqNum(Convert.ToInt32(parts[0]));
cache_.SetNextTargetMsgSeqNum(Convert.ToInt32(parts[1]));
}
}
}
}

If I look at the current memory usage of our PROD QuickFixN code, which is using these files, the memory footprint is pretty much exactly the total bytes for these files, which is what I would expect looking at how the FileStore.ConstructFromFileCache() method works (shown above)

So not really sure that the Reset approach is going to help that much
So what choices do we have to maintain a decent memory footprint for our application?
Could someone advice what we should be looking at doing?
Right now we restart the app manually every 5 days, and from there it builds up to about 2GB over 5 days, but we would be keen to find a more programmatic solution
Overview
So we use QuickFixN within some production code. We have observed that over a period of 4-5 days the memory footprint of our app grows up to around 2GB.
We profiled the app, and can see that the cause appears to be FileStore where the
offsets_Dictionary is storing too much dataOne thing to note, is that left alone, our app rarely restarts
I have downloaded the QuickFixN code and been digging about to see where the
offsets_is used and how it is cleared, and the following is what I seeFileStore
The
FileStoreclass contains theoffsets_which is only cleared, when theConstructFromFileCache()method is called. Which in turn is called when theFileStore.open()method is called, which is only called under 2 conditionsFileStoreconstructionReset()called onFileStoreSo I was thinking perhaps the
Resetneeds to be called. But by whom and when?SessionState
So I dug some more, and can see that the
FileStore.Reset()is called fromSessionState.Reset(string reason). Which in turn is called by various other call sites fromSession.Session
SessionState.Reset()looks like an integral part of the QuickFixN implementation, so these call sites are obviously correct and tested by this repo. Basically I trust the existingSessioncalls to toSessionState.Reset()So the question
Is this memory footprint normal, or is specific QuickFixN application code expected to also call the
Session.Reset()which will call the callsites I mention above? Where the end result could be a call to theFileStore.ConstructFromFileCache.However looking into this, I am not sure a
Resetwould work, as from what I can tell theFileStore.ConstructFromFileCache()method would read the contents of the files shown in image below to construct theoffsets_. Which is obviously will just fill theoffsets_straight back up.If I look at the current memory usage of our PROD QuickFixN code, which is using these files, the memory footprint is pretty much exactly the total bytes for these files, which is what I would expect looking at how the
FileStore.ConstructFromFileCache()method works (shown above)So not really sure that the
Resetapproach is going to help that muchSo what choices do we have to maintain a decent memory footprint for our application?
Could someone advice what we should be looking at doing?
Right now we restart the app manually every 5 days, and from there it builds up to about 2GB over 5 days, but we would be keen to find a more programmatic solution