I have a few actions in my .NET MVC application that go through a decent amount of data and return a JSON object to my views. In order to speed things up a little bit, I've started caching the JSON objects and returning those instead of going through all of the data if only a short time has passed:
System.Web.HttpContext.Current.Cache.Insert(System.Web.HttpContext.Current.User.Identity.Name + "WB", result, null, DateTime.UtcNow.AddMinutes(1), TimeSpan.Zero);
// result is the object that gets converted to JSON
result = new
{
TopDepartures = TopDepartures.ToArray(),
YesterdayFlights = YesterdayFlights.Count(),
TodayFlights = TodayFlights.Count(),
TomorrowFlights = TomorrowFlights.Count(),
LastMonthPax = LastMonthPax.ToString("#,##0"),
YesterdayPax = YesterdayPax.ToString("#,##0"),
PaxMonthToDate = PaxMonthToDate.ToString("#,##0"),
FirstCheckInLocalTime = FirstCheckIn.EstimatedCheckIn.ToString("HH:mm"),
FirstCheckInOrigin = FirstCheckIn.OriginIATA,
FirstCheckInDestination = FirstCheckIn.DestinationIATA,
FirstCheckInSDT = FirstCheckIn.ScheduledDepartureTime.ToString("HH:mm"),
FirstCheckInSAT = FirstCheckIn.ScheduledArrivalTime.ToString("HH:mm"),
FirstCheckInFlightNo = FirstCheckIn.CarrierCode + " " + FirstCheckIn.FlightNo,
LastCheckInLocalTime = LastCheckIn.EstimatedCheckIn.ToString("HH:mm"),
LastCheckInOrigin = LastCheckIn.OriginIATA,
LastCheckInDestination = LastCheckIn.DestinationIATA,
LastCheckInSDT = LastCheckIn.ScheduledDepartureTime.ToString("HH:mm"),
LastCheckInSAT = LastCheckIn.ScheduledArrivalTime.ToString("HH:mm"),
LastCheckInFlightNo = LastCheckIn.CarrierCode + " " + LastCheckIn.FlightNo,
TomorrowFirstCheckInLocalTime = TomorrowFirstCheckIn.EstimatedCheckIn.ToString("HH:mm"),
TomorrowFirstCheckInOrigin = TomorrowFirstCheckIn.OriginIATA,
TomorrowFirstCheckInDestination = TomorrowFirstCheckIn.DestinationIATA,
TomorrowFirstCheckInSDT = TomorrowFirstCheckIn.ScheduledDepartureTime.ToString("HH:mm"),
TomorrowFirstCheckInSAT = TomorrowFirstCheckIn.ScheduledArrivalTime.ToString("HH:mm"),
TomorrowFirstCheckInFlightNo = TomorrowFirstCheckIn.CarrierCode + " " + TomorrowFirstCheckIn.FlightNo,
};
I do a check at the beginning of the Action:
var cachedResult = System.Web.HttpContext.Current.Cache.Get(System.Web.HttpContext.Current.User.Identity.Name + "WB");
if (cachedResult != null)
{
return Json(cachedResult, JsonRequestBehavior.AllowGet);
}
The problem is, ever since I implemented this, Ninject has been periodically firing OutOfMemory exceptions. I've been researching this but I haven't been able to find anything explicitly referencing a link between caching and Ninject OutOfMemory exceptions. There also doesn't appear to be a specific pattern that causes the exception to be fired. It will run fine for hours of changes and testing and then suddenly the site will stop working and I'll see the OutOfMemory exception in the logs. Then other times it'll happen immediately.
This Action is called and the object retrieved by an AJAX call on my view, if that information is relevant.
Here is the stack trace:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Collections.Generic.HashSet`1.SetCapacity(Int32 newSize, Boolean forceNewHashCodes)
at System.Collections.Generic.HashSet`1.IncreaseCapacity()
at System.Collections.Generic.HashSet`1.AddIfNotPresent(T value)
at System.Collections.Generic.HashSet`1.Add(T item)
at Ninject.Activation.Caching.ActivationCache.AddActivatedInstance(Object instance)
at Ninject.Activation.Strategies.ActivationCacheStrategy.Activate(IContext context, InstanceReference reference)
at Ninject.Activation.Pipeline.<>c__DisplayClass2.<Activate>b__0(IActivationStrategy s)
at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action)
at Ninject.Activation.Pipeline.Activate(IContext context, InstanceReference reference)
at Ninject.Activation.Context.ResolveInternal(Object scope)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass15.<Resolve>b__f(IBinding binding)
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__94`1.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Ninject.Infrastructure.Language.ExtensionsForIEnumerable.ToArraySlow(IEnumerable series, Type elementType)
at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.ResolveInternal(Object scope)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass15.<Resolve>b__f(IBinding binding)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent)
at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
at Ninject.Activation.Context.ResolveInternal(Object scope)
at Ninject.Activation.Context.Resolve()
at Ninject.KernelBase.<>c__DisplayClass15.<Resolve>b__f(IBinding binding)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at Ninject.ResolutionExtensions.Get(IResolutionRoot root, Type service, IParameter[] parameters)
at AirlineChoiceDashboard.WebUI.Infrastructure.NinjectControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) in D:\Development\Airline Choice Dashboard\Source Code\Development\WebUI\Infrastructure\NinjectControllerFactory.cs:line 38