Memory Leak - LOH

DoubleVerify
Posts: 1
Joined: Thu Jun 30, 2016 9:14 am

Memory Leak - LOH

Postby DoubleVerify » Thu Jun 30, 2016 9:40 am

Hi,

When calling WURFLManager.GetDeviceForRequest(string) method with an Android useragent, the call stack creates memory inside LOH (Large Object Heap).
I was profiling WURFL and disassembled it and found out that it happens due to allocation of a new List<string> for each call to the method above.

The following is the call stack that make the most garbage into LOH:

UserAgenrProcessorMemoryInspector.Program.Main(String[])
-> UserAgenrProcessorMemoryInspector.Program.Run()
-> DoubleVerify.TP.Service.Data.UserAgentData.ProcessTemp(String)
-> DoubleVerify.TP.Service.Data.UserAgentData.TryGetWurflBrowser(String, InternalUserAgentData, Nullable<Int16>&, String&)
-> WurflWrapperVersion1_7.WurflWrapper1_7.GetCapabilities(String, String[])
-> WurflWrapperVersion1_7.WurflWrapper1_7.GetVirtualCapabilities(String, String[])
-> WURFL.WURFLManager.GetDeviceForRequest(String)
-> WURFL.WurflWorkerService.GetDeviceForRequest(WURFLRequest, MatchMode, Boolean)
-> WURFL.Devices.DeviceRepository.GetMatcherResponseByRequest(WURFLRequest)
-> WURFL.Matchers.Chains.MatcherChain.Match(WURFLRequest)
-> WURFL.Matchers.Chains.MatcherChain.Match(WURFLRequest)
-> WURFL.Matchers.Core.AbstractMatcher.Match(WURFLRequest)
-> WURFL.Matchers.Core.AbstractMatcher.ApplyConclusiveMatch(WURFLRequest)
-> WURFL.Matchers.Browsers.AndroidMatcher.LookForMatchingUserAgent(String)
-> WURFL.Matchers.StringMatcher.LongestCommonPrefixMatcher.Match(ICollection<String>, String, Int32)
-> System.Collections.Generic.List..ctor(IEnumerable<T>)

I was debugging WURFL code and saw that for the given call stack above, the List was instantiated with about 24,000 strings.
24,000 objects times 8 bytes for a reference type is more than 85,000, which means that the List will be allocated on the LOH.
Important to note: I've noticed this memory issue only for Android user agents.
This causes a huge penalty to our system as doing GC on the LOH is much more expensive, and more than that, it causes LOH to be fragmented over time.

Is there a workaround for making your code not to instantiate big objects on the LOH when calling to WURFLManager.GetDeviceForRequest(string) ?

Thanks,

Lior,
DoubleVerify

aaronp
Posts: 223
Joined: Wed Dec 09, 2015 12:39 pm

Re: Memory Leak - LOH

Postby aaronp » Wed Jul 20, 2016 3:21 pm

Per our email conversation:

We have made updates to the API (v1.7.1.1) so that only one static instance of List<string> is instantiated (during engine startup), as opposed to an instance per each request. While the List is still in LOH (given the size), the garbage collector will never remove it. In turn, performance is enhanced and there is no memory fragmentation.


Who is online

Users browsing this forum: No registered users and 1 guest