Hi guys,
First to give you some background information before going into more details (if you don't want to read it all you can simply jump to the bottom).
We have had complains from our customers that their nopCommerce websites restart from time to time.
All these customers turn out to be using a shared hosting and the reasons for the restarts is that their website application pools hit their memory limit, which on a shared hosting is usually between 300-500 MB with some shared hosting offering up to 800 MB.
Since we run more than 30 nopCommerce websites ourselves on a single server and it is also important for us to use as little memory as possible and we already know the fact that changing the application pool to run as a 32 bit application decreases the memory usage twice. Actually all our 30+ theme demos run as 32 bit applications without any issues and consume very little memory around 200-300 MB.
Actually most of the hosting companies are already aware of this improvement and should have already done this in advance. But even after ensuring that the website is running as 32 bit application they still hit the memory limits from time to time.
Why is this happening when the average memory consumption is around up to 300 MB (when running as 32 bit application)?
The simple answer is that there are cases when there is a really high memory consumption that causes the memory to go far beyond the 800 MB memory limit. If you are like us running your websites without any memory limits, you won't even notice that because once the Garbage Collector is triggered it will remove any unused memory and your website memory consumption will be back to normal. But if you are using a shared hosting and have a memory limit on your application pool you will definitely know when this happens as your website will be restarted.
So I decided to do some memory profiling to see why this really happens.
Since the customers complained that the memory limit is hit after installing our plugins I run two nopCommerce websites - a brand new nopCommerce 3.80 (no source code version) with none of our plugins installed and another one with all our plugins intalled.
Both sites performed almost the same with a slight difference around 15 MB, which means that these memory spikes are not directly caused by any of our plugins. So the problem seems to be somewhere else and not directly caused by a specific plugin.
Why do these customers experience these issues after installing the plugins when there are no any memory consumption differences with and without the plugins?
The only thing that happens when installing a new plugin is that nopCommerce is being restarted after the plugin is installed.
So I went in the administration and hit the Restart Application button, which is the same that happens after a plugin is being installed and then I noticed that the memory goes up and it starts growing faster if you try to access the website while it is being restarted.
I notice the memory goes from around 200 MB to up to 700MB and if you keep doing this you might end up with more than 1 GB (see the end of the video).
Since all out themes come with a least 10 plugins, then this means that our clients will have their website restarted at least 10 times during the installation of the theme and then the probability that they will hit the memory limit is quite high.
I recorded a video that easily illustrates this with a nopCommerce running without any plugins and simply restarting it a few times and making requests to the website while it is being restarted.
So this already proved to me that the issue with hitting a high memory usage is not caused by any of our plugins since as shown in the video we don't have any plugins (instead of the default ones) installed. But this still does not change the fact that shared hosting users may experience frequent restarts of their websites after installing several plugins one after another.
Why nopCommerce uses so much memory after a restart?
I decided to get to the bottom of this and downloaded the trial version of dotMemory and snapshot the memory usage during the peak time memory consumption (you need to be very quick as the GC may reduce the memory at any point).
It turned out the there are 500 MB ... yes 500 MB in Strings allocated in the memory heap.
When investigated who allocated so much stings in the memory it turned out that it is the constructor of the BrowscapXmlHelper class.
You can easily spot why this happens as there is a huge 40 MB file App_Data\browscap.xml that is being loaded in a String into the memory. Then there are several Replace methods that actually create new strings rather than modifying the existing one.
By simply commenting the the Initialize method invocation in the constructor of the BrowscapXmlHelper, then I couldn't make my nopCommerce to take more than 200 MB even after several restarts.
So the implementation of the BrowscapXmlHelper class needs to be corrected to ensure all nopCommerce users will run smoothly their nopCommerce websites on a shared hosting.
Hope this help!
Thanks,
Boyko