I am currently developing reports for a web based solution using Telerik Reporting and the report viewer. The reports created could display a different image in the detail section for every single record. As a result I have a function that loads the appropriate image. When I first implemented this I quickly realized that I had a memory usage problem. The problem was that an image object was being loaded into memory for each record on the report.
To attempt to solve this problem I created a static variable that stores the images that have been loaded into memory already. When the original method is called it checks to see if the image is already in memory. If the image is found in memory it returns the located image otherwise the image is loaded. Additionally, logic is built in so that an image is only retained in memory for 15 minutes since the last time it was accessed. With this approach I was able to decrease the memory usage and increase the performance. For simple implementations this solution would be enough but unfortunately the current requirements are more complex.
The problem is that I am governed by regulations that dictate the size of the images based on the number that are displayed. Since this could be different for each detail record my solution is to create a composite image in memory that I can size to meet my requirements. Now instead of working with possibly 100 images the amount of images that I could be working with could be in the tens of thousands. There are some rules I can put in place to limit the amount of unique images but I am still concerned about the amount of memory that will be used as the number of users grow and more reports are generated.
The best solution that I can think of is to only keep the image in memory for as long as it is required but I can not determine a good way to accomplish this. The static variable is shared by the entire application (every user) and the image can not be disposed of until report generation is complete. My current goals to solve this problem are:
To attempt to solve this problem I created a static variable that stores the images that have been loaded into memory already. When the original method is called it checks to see if the image is already in memory. If the image is found in memory it returns the located image otherwise the image is loaded. Additionally, logic is built in so that an image is only retained in memory for 15 minutes since the last time it was accessed. With this approach I was able to decrease the memory usage and increase the performance. For simple implementations this solution would be enough but unfortunately the current requirements are more complex.
The problem is that I am governed by regulations that dictate the size of the images based on the number that are displayed. Since this could be different for each detail record my solution is to create a composite image in memory that I can size to meet my requirements. Now instead of working with possibly 100 images the amount of images that I could be working with could be in the tens of thousands. There are some rules I can put in place to limit the amount of unique images but I am still concerned about the amount of memory that will be used as the number of users grow and more reports are generated.
The best solution that I can think of is to only keep the image in memory for as long as it is required but I can not determine a good way to accomplish this. The static variable is shared by the entire application (every user) and the image can not be disposed of until report generation is complete. My current goals to solve this problem are:
- Keep memory usage at a minimum (only one unique image loaded for all users using the application)
- Only keep an image an memory for as long as it is needed by current report requests
- Reduce the impact on the end user experience
At this point I have accomplished the first goal but I am still not satisfied with the solution to the second goal. I have some ideas on how to keep track of which report jobs are using an image while at the same time only having the single image loaded. I am concerned that by building on this extra layer of tracking it will have a significant impact on performance. Before I went down that road I wanted to check and see if I am trying to over complicate an issue that doesn't need to be complicated. Is their a simpler solution to what I am trying to accomplish using Telerik Reporting?