Xamarin.Profilerでメモリリーク解析2(Android)
※[悲報]
下記のスクリプト、Xamarin Profilerの0.32以前でないと動かないようです…
そのうち直すかもですが、元のライブラリーが対応してくれないと難しいかもです…(;´・ω・)
Xamarin.Profilerでメモリリーク解析(Android) - omanuke-ekunamoの日記の続きでSnapshot間のオブジェクトの増減を見れるようにしました。
のような場合でSnapshot8と12の間の増減を見たい場合、
dumpDiff<|heapDiff 8 12
とすると
========= Heap Diff 8 to 12 ================================= [13807] AppCommon.Controls.CustomNavBtnItem 3 [791] Java.Interop.JniPeerMembers.JniInstanceFields 3 [790] Java.Interop.JniPeerMembers.JniInstanceMethods 3 [793] Java.Interop.JniPeerMembers.JniStaticFields 3 [792] Java.Interop.JniPeerMembers.JniStaticMethods 3 [445] Java.Interop.JniType 3 [20868] Microsoft.FSharp.Core.PrintfImpl.Final1@224<Microsoft.FSharp.Core.Unit,System.String,System.String,System.Int32> 3 [2687] System.Action 3 [337] System.AsyncCallback 3 [588] System.Collections.Concurrent.ConcurrentDictionary.Node<System.IntPtr,System.IDisposable> 3 [4567] System.Collections.Generic.Dictionary.Entry<System.String,System.Object>[] 3 [843] System.Collections.Generic.Dictionary<System.Type,Java.Interop.JniPeerMembers.JniInstanceMethods> 3 [13118] System.Collections.Generic.List<Xamarin.Forms.Behavior> 3 [13136] System.Collections.Generic.List<Xamarin.Forms.TriggerBase> 3 [696] System.Collections.Hashtable 3 [3604] System.Collections.Hashtable.bucket[] 3 [13108] System.Collections.ObjectModel.ObservableCollection.SimpleMonitor<Xamarin.Forms.Behavior> 3 [13114] System.Collections.ObjectModel.ObservableCollection.SimpleMonitor<Xamarin.Forms.TriggerBase> 3 [13780] System.Net.Sockets.NetworkStream 3 [2929] System.Random 3 [2922] System.Threading.IThreadPoolWorkItem[] 3 [2908] System.Threading.ThreadPoolWorkQueue.WorkStealingQueue 3 [2928] System.Threading.ThreadPoolWorkQueueThreadLocals 3 [20843] System.Tuple<Microsoft.FSharp.Core.FSharpFunc<Microsoft.FSharp.Core.FSharpFunc<Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.PrintfImpl.PrintfEnv<Microsoft.FSharp.Core.Unit,System.String,System.String>>,Microsoft.FSharp.Core.FSharpFunc<System.Int32,System.String>>,System.Int32> 3 [20365] TAC.Model.JsonParseUtil.JsonParser<TAC.Model.CommonType.PosSum[]> 3 [21334] Trading.Chart.BaseTypes.RendererPriority 3 [23710] Trading.Chart.Processor.CalcType 3 [25283] Trading.Chart.Processor.ProcessDataType 3 [20879] Trading.Chart.Proto.ViewType 3 [21224] Trading.Chart.ViewDataState 3 [13101] Xamarin.Forms.AttachedCollection<Xamarin.Forms.Behavior> 3 [13111] Xamarin.Forms.AttachedCollection<Xamarin.Forms.TriggerBase> 3 [12896] Xamarin.Forms.IGestureRecognizer[] 3 [13214] Xamarin.Forms.Image 3 [13211] Xamarin.Forms.TapGestureRecognizer 3 [13833] Android.Views.GestureDetector 4 [1939] Android.Views.MotionEvent 4 [20855] Microsoft.FSharp.Core.PrintfImpl.basicNumberToString@584-220 4 [17874] System.Func<System.Int32,System.Boolean> 4 [17903] System.Lazy.Boxed<Android.Views.GestureDetector> 4 [5131] TAC.Model.JsonParseUtil.JsonParser<System.Boolean> 4 [5491] TAC.Model.TLineMode 4 [14779] Xamarin.Forms.Platform.Android.ImageRenderer 4 [20752] Microsoft.FSharp.Collections.MapTree.MapOne<System.String,Microsoft.FSharp.Collections.FSharpList<System.Tuple<System.String,System.String,Microsoft.FSharp.Collections.FSharpList<System.Tuple<System.String,System.Int32>>>>> 5 [24947] Microsoft.FSharp.Core.PrintfImpl.Final1@224<Microsoft.FSharp.Core.Unit,System.String,System.String,System.Int64> 5
などと[typeId] 型名 増減 という感じで表示します。
怪しい参照などあったら
dumpAllPathByType (hShot 12) 21212
などとみたいSnapshotとtypeIdを指定すると被参照パスみれます。
スクリプトこちら(´・ω・`)
#I @"D:\GitHub\heap-shot\HeapShot.Reader\obj\Debug" //#I @"d:\Dropbox" #r "heapshot.reader.dll" open HeapShot.Reader open System.IO let path= @"D:\GitHub\heap-shot\HeapShot" //let path= @"D:\Dropbox" let fName=Path.Combine(path,"r_.mlpd") let omap=new ObjectMapReader(fName) omap.Read() let ls=omap.LastSnapshot let hShot i=omap.HeapShots.[i] //dummy listener let listener={new IProgressListener with member this.ReportProgress(msg,progress)= printfn"[progress] %s %f" msg progress member this.Cancelled=false} //node in PathTree->o and name let nodeToO (pTree:PathTree) node= let o=pTree.GetNodeObject node let name=ls.GetObjectTypeName o o,name //dump each reference path let rec dumpPath (pTree:PathTree) depth maxDepth node= let tabs="".PadLeft(depth*4) let o,name=nodeToO pTree node printfn "%s%s(%d)" tabs name o if depth<maxDepth then pTree.GetChildNodes node |>Seq.iter(fun cNode->dumpPath pTree (depth+1) maxDepth cNode) //dump all reference path let dumpAllPath (pTree:PathTree) maxDepth= pTree.GetRootNodes() |>Seq.iter(fun rNode-> let o,name=nodeToO pTree rNode printfn"----[%x] %s ------" o name dumpPath pTree 0 maxDepth rNode) //dump all reference path for type let dumpAllPathByType (ls:HeapSnapshot) t= let pTree=ls.GetRoots(listener,t) //dump all with max depth dumpAllPath pTree 100 //type,name,object count from type name let printTnc (t,n,c)=printfn"[%d] %s %d" t n c let dumpTncs tncs=tncs|>Seq.iter printTnc let tncByType (ls:HeapSnapshot) t= let n=ls.GetTypeName t let os=ls.GetObjectsByType t let c=os|>Seq.length t,n,c let toAllTncs (ls:HeapSnapshot)= ls.GetTypes() |>Seq.map (tncByType ls) |>Seq.filter(fun(_,_,c)->c>0) |>Seq.sortBy(fun(_,n,_)->n) let tncsByKey ls key= toAllTncs ls|>Seq.filter(fun(_,n,_)->n.Contains(key)) //diff let tncsDiff tncs1 tncs2= let rec loop acc tncs1 tncs2= match (tncs1,tncs2) with |[],[]->acc|>List.rev |[],(t,n,c)::ts->loop ((t,n,c)::acc) [] ts |(t,n,c)::ts,[]->loop ((t,n,-c)::acc) ts [] |(t1,n1,c1)::ts1,(t2,n2,c2)::ts2-> let c=Microsoft.FSharp.Core.Operators.compare n1 n2 if c=0 then loop((t2,n2,c2-c1)::acc) ts1 ts2 elif c<0 then loop((t1,n1,-c1)::acc) ts1 tncs2 else loop((t2,n2,c2)::acc) tncs1 ts2 loop [] (List.ofSeq tncs1) (List.ofSeq tncs2) let heapDiff fromI toI= printfn"========= Heap Diff %d to %d =================================" fromI toI let tncs i=hShot i|>toAllTncs tncsDiff (tncs fromI) (tncs toI) let dumpDiff diff= diff |>List.filter(fun(_,_,diff)->diff<>0) |>List.sortBy(fun(_,_,d)->d) |>List.iter printTnc let dumpTncByType (ls:HeapSnapshot) t=[tncByType ls t]|>dumpTncs omap.HeapShots.Count dumpDiff<|heapDiff 8 12 dumpDiff<|heapDiff 3 7 dumpAllPathByType (hShot 23) 21212