Improving memory with performance overhead in a multi-threaded distributed application

I was able to improve web application performance 10% faster than before. At the same time, I noticed that the memory usage doubled !!!

Test application: calling a web service, performing a complex business action * [number of users] * [number of times]

I check my change code, but nothing suspicious is to use more memory .. (all I did was delete the lines of code that serialize the DataSet to byte [] and saved it in cache) I checked again and again in multi-threaded test:

  • As I missed more and more code ( performance improved - memory rose )
  • How I repeated bad code in a loop (performance was bad - memory went low)

Can anyone explain why ????

Code below:

To: (Cycle time: 100% Memory 100%)

outStream = new MemoryStream(); new BinaryFormatter().Serialize(outStream, stateData); outStream.Close(); SessionSettings.StateData_Set(stateId, outStream.ToArray()); outStream.Dispose(); 

After selecting 1: (Cycle time: 200% Memory 50%)

 for (int i = 0; i < 20; i++) { outStream = new MemoryStream(); new BinaryFormatter().Serialize(outStream, stateData); } outStream.Close(); SessionSettings.StateData_Set(stateId, outStream.ToArray()); outStream.Dispose(); 

After selecting 2: (Cycle time: 90% Memory 200%)

  //outStream = new MemoryStream(); //new BinaryFormatter().Serialize(outStream, stateData); //outStream.Close(); SessionSettings.StateData_Set(stateId, null); //outStream.Dispose(); 

SessionSettings.StateData_Set places an object in

 dictionary<string,dictionary<string, object>> 

which means

 <Sessions<DataKey,DataObject>> 

at the end of each cycle, the internal dictionary deletes the entry, and at the end of each user session, the entire internal dictionary is deleted from the external dictionary.

+4
source share
2 answers

Another suggestion: if your application allocates too much memory (possibly through frequent serialization), the CLR will start the GC much more often. Observing the performance counter -> Time in the GC, you will notice that the GC eats up a lot of CPU - I saw scenarios above 40%. This is especially true if your data arrays are large and byte [] is in LOH.

By limiting these distributions, GC will be triggered much less often, which will lead to increased application performance. The reason for the observed increase in memory may be that the managed heap now works more in a healthy area.

To find a more reliable explanation, send some performance metrics: before optimizations and after your optimizations. It would be interesting: the total heap size, the time spent in the GC.

+4
source

Since you have not provided any code and only a brief explanation, this is more a mystery than a question.

Thus, it is possible that 10 users accessed CACHED DATASET at approximately the same time. CACHED DATASET was blocked and viewed by users SYNCHRONOUSLY (one at a time). This will not work well in a multi-threaded test, but will use a small amount of memory.

Perhaps the REPLICATED DATA SITE (without cache) was accessing 10 users at about the same time. Each user will have their own copy of the RECORDED TYPE. Without blocking / synchronized access and multiple copies of DATASET, memory increased, but performance improved.

+3
source

Source: https://habr.com/ru/post/1397855/


All Articles