├── .gitignore
├── Assembly-CSharp.csproj.DotSettings
├── Assets
├── Sample.meta
├── Sample
│ ├── AnimatorController.controller
│ ├── AnimatorController.controller.meta
│ ├── Game.cs
│ ├── Game.cs.meta
│ ├── Sample.unity
│ ├── Sample.unity.meta
│ ├── SampleMemorySnapshot.cs
│ ├── SampleMemorySnapshot.cs.meta
│ ├── Unit.cs
│ ├── Unit.cs.meta
│ ├── UnitComponent.cs
│ ├── UnitComponent.cs.meta
│ ├── UnitVisualSettings.cs
│ ├── UnitVisualSettings.cs.meta
│ ├── UnitsGroup.cs
│ └── UnitsGroup.cs.meta
├── UnityHeapCrawler.meta
└── UnityHeapCrawler
│ ├── CrawlItem.cs
│ ├── CrawlItem.cs.meta
│ ├── CrawlOrder.cs
│ ├── CrawlOrder.cs.meta
│ ├── CrawlSettings.cs
│ ├── CrawlSettings.cs.meta
│ ├── HeapSnapshotCollector.cs
│ ├── HeapSnapshotCollector.cs.meta
│ ├── InstanceStats.cs
│ ├── InstanceStats.cs.meta
│ ├── ReferenceEqualityComparer.cs
│ ├── ReferenceEqualityComparer.cs.meta
│ ├── SizeFormat.cs
│ ├── SizeFormat.cs.meta
│ ├── SizeMode.cs
│ ├── SizeMode.cs.meta
│ ├── SnapshotHistory.cs
│ ├── SnapshotHistory.cs.meta
│ ├── TypeData.cs
│ ├── TypeData.cs.meta
│ ├── TypeEx.cs
│ ├── TypeEx.cs.meta
│ ├── TypeSizeMode.cs
│ ├── TypeSizeMode.cs.meta
│ ├── TypeStats.cs
│ └── TypeStats.cs.meta
├── Doxyfile
├── DreamMemoryAnalyzer.csproj.DotSettings
├── LICENSE
├── Packages
└── manifest.json
├── ProjectSettings
├── AudioManager.asset
├── ClusterInputManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshAreas.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── PresetManager.asset
├── ProjectSettings.asset
├── ProjectVersion.txt
├── QualitySettings.asset
├── TagManager.asset
├── TimeManager.asset
└── UnityConnectSettings.asset
├── README.md
├── snapshot-example-diff
├── 2-static-fields.txt
├── 3-hierarchy.txt
├── 7-unity_objects.txt
├── generic-static-fields.txt
├── log.txt
├── types-native.txt
├── types-self.txt
├── types-total.txt
└── types
│ ├── Sprite.txt
│ └── Texture2D.txt
└── snapshot-example
├── 1-user-roots.txt
├── 2-static-fields.txt
├── 3-hierarchy.txt
├── 5-prefabs.txt
├── 6-scriptable_objects.txt
├── 7-unity_objects.txt
├── generic-static-fields.txt
├── log.txt
├── types-native.txt
├── types-self.txt
├── types-total.txt
└── types
├── Cubemap.txt
├── CubemapArray.txt
├── RenderTexture.txt
├── Sprite.txt
├── Texture.txt
├── Texture2D.txt
├── Texture2DArray.txt
├── Texture3D.txt
└── Unit.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs
2 | Library
3 | *.sln
4 | *.sln.DotSettings.user
5 | *.userprefs
6 | *.suo
7 | Temp
8 | obj
9 | *.csproj
10 | .idea
11 | *.iml
12 |
--------------------------------------------------------------------------------
/Assembly-CSharp.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/Assets/Sample.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c4e6cb2d522efd34ba0d1dfd6f6fef55
3 | folderAsset: yes
4 | timeCreated: 1513952476
5 | licenseType: Pro
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/Sample/AnimatorController.controller:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!91 &9100000
4 | AnimatorController:
5 | m_ObjectHideFlags: 0
6 | m_PrefabParentObject: {fileID: 0}
7 | m_PrefabInternal: {fileID: 0}
8 | m_Name: AnimatorController
9 | serializedVersion: 5
10 | m_AnimatorParameters: []
11 | m_AnimatorLayers: []
12 |
--------------------------------------------------------------------------------
/Assets/Sample/AnimatorController.controller.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f3e8259a844d17e4795cac35d134af12
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 9100000
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Sample/Game.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace Sample
5 | {
6 | public class Game
7 | {
8 | public static Game Instance = new Game();
9 |
10 | [NotNull]
11 | public UnitsGroup Enemies;
12 |
13 | [NotNull]
14 | private Unit player;
15 |
16 | [NotNull]
17 | private List allUnits = new List();
18 |
19 | public Game()
20 | {
21 | player = new Unit();
22 | var pet = new Unit();
23 | var enemy1 = new Unit();
24 | var enemy2 = new Unit();
25 |
26 | player.Pet = pet;
27 |
28 | allUnits.Add(player);
29 | allUnits.Add(pet);
30 | allUnits.Add(enemy1);
31 | allUnits.Add(enemy2);
32 |
33 | Enemies = new UnitsGroup(enemy1, enemy2);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Assets/Sample/Game.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 385d22c27a6b8184b84a07b0ea2c8242
3 | timeCreated: 1513952476
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Sample/Sample.unity:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!29 &1
4 | OcclusionCullingSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_OcclusionBakeSettings:
8 | smallestOccluder: 5
9 | smallestHole: 0.25
10 | backfaceThreshold: 100
11 | m_SceneGUID: 00000000000000000000000000000000
12 | m_OcclusionCullingData: {fileID: 0}
13 | --- !u!104 &2
14 | RenderSettings:
15 | m_ObjectHideFlags: 0
16 | serializedVersion: 9
17 | m_Fog: 0
18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
19 | m_FogMode: 3
20 | m_FogDensity: 0.01
21 | m_LinearFogStart: 0
22 | m_LinearFogEnd: 300
23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
26 | m_AmbientIntensity: 1
27 | m_AmbientMode: 0
28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
30 | m_HaloStrength: 0.5
31 | m_FlareStrength: 1
32 | m_FlareFadeSpeed: 3
33 | m_HaloTexture: {fileID: 0}
34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
35 | m_DefaultReflectionMode: 0
36 | m_DefaultReflectionResolution: 128
37 | m_ReflectionBounces: 1
38 | m_ReflectionIntensity: 1
39 | m_CustomReflection: {fileID: 0}
40 | m_Sun: {fileID: 0}
41 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
42 | m_UseRadianceAmbientProbe: 0
43 | --- !u!157 &3
44 | LightmapSettings:
45 | m_ObjectHideFlags: 0
46 | serializedVersion: 11
47 | m_GIWorkflowMode: 0
48 | m_GISettings:
49 | serializedVersion: 2
50 | m_BounceScale: 1
51 | m_IndirectOutputScale: 1
52 | m_AlbedoBoost: 1
53 | m_TemporalCoherenceThreshold: 1
54 | m_EnvironmentLightingMode: 0
55 | m_EnableBakedLightmaps: 1
56 | m_EnableRealtimeLightmaps: 1
57 | m_LightmapEditorSettings:
58 | serializedVersion: 10
59 | m_Resolution: 2
60 | m_BakeResolution: 40
61 | m_AtlasSize: 1024
62 | m_AO: 0
63 | m_AOMaxDistance: 1
64 | m_CompAOExponent: 1
65 | m_CompAOExponentDirect: 0
66 | m_Padding: 2
67 | m_LightmapParameters: {fileID: 0}
68 | m_LightmapsBakeMode: 1
69 | m_TextureCompression: 1
70 | m_FinalGather: 0
71 | m_FinalGatherFiltering: 1
72 | m_FinalGatherRayCount: 256
73 | m_ReflectionCompression: 2
74 | m_MixedBakeMode: 2
75 | m_BakeBackend: 0
76 | m_PVRSampling: 1
77 | m_PVRDirectSampleCount: 32
78 | m_PVRSampleCount: 500
79 | m_PVRBounces: 2
80 | m_PVRFilterTypeDirect: 0
81 | m_PVRFilterTypeIndirect: 0
82 | m_PVRFilterTypeAO: 0
83 | m_PVRFilteringMode: 1
84 | m_PVRCulling: 1
85 | m_PVRFilteringGaussRadiusDirect: 1
86 | m_PVRFilteringGaussRadiusIndirect: 5
87 | m_PVRFilteringGaussRadiusAO: 2
88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5
89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2
90 | m_PVRFilteringAtrousPositionSigmaAO: 1
91 | m_ShowResolutionOverlay: 1
92 | m_LightingDataAsset: {fileID: 0}
93 | m_UseShadowmask: 1
94 | --- !u!196 &4
95 | NavMeshSettings:
96 | serializedVersion: 2
97 | m_ObjectHideFlags: 0
98 | m_BuildSettings:
99 | serializedVersion: 2
100 | agentTypeID: 0
101 | agentRadius: 0.5
102 | agentHeight: 2
103 | agentSlope: 45
104 | agentClimb: 0.4
105 | ledgeDropHeight: 0
106 | maxJumpAcrossDistance: 0
107 | minRegionArea: 2
108 | manualCellSize: 0
109 | cellSize: 0.16666667
110 | manualTileSize: 0
111 | tileSize: 256
112 | accuratePlacement: 0
113 | debug:
114 | m_Flags: 0
115 | m_NavMeshData: {fileID: 0}
116 | --- !u!1 &234683256
117 | GameObject:
118 | m_ObjectHideFlags: 0
119 | m_PrefabParentObject: {fileID: 0}
120 | m_PrefabInternal: {fileID: 0}
121 | serializedVersion: 5
122 | m_Component:
123 | - component: {fileID: 234683257}
124 | m_Layer: 0
125 | m_Name: Child4
126 | m_TagString: Untagged
127 | m_Icon: {fileID: 0}
128 | m_NavMeshLayer: 0
129 | m_StaticEditorFlags: 0
130 | m_IsActive: 1
131 | --- !u!4 &234683257
132 | Transform:
133 | m_ObjectHideFlags: 0
134 | m_PrefabParentObject: {fileID: 0}
135 | m_PrefabInternal: {fileID: 0}
136 | m_GameObject: {fileID: 234683256}
137 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
138 | m_LocalPosition: {x: 0, y: 0, z: 0}
139 | m_LocalScale: {x: 1, y: 1, z: 1}
140 | m_Children: []
141 | m_Father: {fileID: 539936832}
142 | m_RootOrder: 3
143 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
144 | --- !u!1 &539936831
145 | GameObject:
146 | m_ObjectHideFlags: 0
147 | m_PrefabParentObject: {fileID: 0}
148 | m_PrefabInternal: {fileID: 0}
149 | serializedVersion: 5
150 | m_Component:
151 | - component: {fileID: 539936832}
152 | m_Layer: 0
153 | m_Name: HierarchyObject
154 | m_TagString: Untagged
155 | m_Icon: {fileID: 0}
156 | m_NavMeshLayer: 0
157 | m_StaticEditorFlags: 0
158 | m_IsActive: 1
159 | --- !u!4 &539936832
160 | Transform:
161 | m_ObjectHideFlags: 0
162 | m_PrefabParentObject: {fileID: 0}
163 | m_PrefabInternal: {fileID: 0}
164 | m_GameObject: {fileID: 539936831}
165 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
166 | m_LocalPosition: {x: -17.593266, y: 14.58786, z: 11.535137}
167 | m_LocalScale: {x: 1, y: 1, z: 1}
168 | m_Children:
169 | - {fileID: 1487508546}
170 | - {fileID: 1600536898}
171 | - {fileID: 1539683785}
172 | - {fileID: 234683257}
173 | - {fileID: 2125243663}
174 | - {fileID: 874905658}
175 | m_Father: {fileID: 0}
176 | m_RootOrder: 2
177 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
178 | --- !u!1 &760734941
179 | GameObject:
180 | m_ObjectHideFlags: 0
181 | m_PrefabParentObject: {fileID: 0}
182 | m_PrefabInternal: {fileID: 0}
183 | serializedVersion: 5
184 | m_Component:
185 | - component: {fileID: 760734943}
186 | - component: {fileID: 760734942}
187 | m_Layer: 0
188 | m_Name: Directional Light
189 | m_TagString: Untagged
190 | m_Icon: {fileID: 0}
191 | m_NavMeshLayer: 0
192 | m_StaticEditorFlags: 0
193 | m_IsActive: 1
194 | --- !u!108 &760734942
195 | Light:
196 | m_ObjectHideFlags: 0
197 | m_PrefabParentObject: {fileID: 0}
198 | m_PrefabInternal: {fileID: 0}
199 | m_GameObject: {fileID: 760734941}
200 | m_Enabled: 1
201 | serializedVersion: 8
202 | m_Type: 1
203 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
204 | m_Intensity: 1
205 | m_Range: 10
206 | m_SpotAngle: 30
207 | m_CookieSize: 10
208 | m_Shadows:
209 | m_Type: 2
210 | m_Resolution: -1
211 | m_CustomResolution: -1
212 | m_Strength: 1
213 | m_Bias: 0.05
214 | m_NormalBias: 0.4
215 | m_NearPlane: 0.2
216 | m_Cookie: {fileID: 0}
217 | m_DrawHalo: 0
218 | m_Flare: {fileID: 0}
219 | m_RenderMode: 0
220 | m_CullingMask:
221 | serializedVersion: 2
222 | m_Bits: 4294967295
223 | m_Lightmapping: 4
224 | m_AreaSize: {x: 1, y: 1}
225 | m_BounceIntensity: 1
226 | m_ColorTemperature: 6570
227 | m_UseColorTemperature: 0
228 | m_ShadowRadius: 0
229 | m_ShadowAngle: 0
230 | --- !u!4 &760734943
231 | Transform:
232 | m_ObjectHideFlags: 0
233 | m_PrefabParentObject: {fileID: 0}
234 | m_PrefabInternal: {fileID: 0}
235 | m_GameObject: {fileID: 760734941}
236 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
237 | m_LocalPosition: {x: 0, y: 3, z: 0}
238 | m_LocalScale: {x: 1, y: 1, z: 1}
239 | m_Children: []
240 | m_Father: {fileID: 0}
241 | m_RootOrder: 1
242 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
243 | --- !u!1 &769026267
244 | GameObject:
245 | m_ObjectHideFlags: 0
246 | m_PrefabParentObject: {fileID: 0}
247 | m_PrefabInternal: {fileID: 0}
248 | serializedVersion: 5
249 | m_Component:
250 | - component: {fileID: 769026272}
251 | - component: {fileID: 769026271}
252 | - component: {fileID: 769026270}
253 | - component: {fileID: 769026269}
254 | - component: {fileID: 769026268}
255 | m_Layer: 0
256 | m_Name: Main Camera
257 | m_TagString: MainCamera
258 | m_Icon: {fileID: 0}
259 | m_NavMeshLayer: 0
260 | m_StaticEditorFlags: 0
261 | m_IsActive: 1
262 | --- !u!81 &769026268
263 | AudioListener:
264 | m_ObjectHideFlags: 0
265 | m_PrefabParentObject: {fileID: 0}
266 | m_PrefabInternal: {fileID: 0}
267 | m_GameObject: {fileID: 769026267}
268 | m_Enabled: 1
269 | --- !u!124 &769026269
270 | Behaviour:
271 | m_ObjectHideFlags: 0
272 | m_PrefabParentObject: {fileID: 0}
273 | m_PrefabInternal: {fileID: 0}
274 | m_GameObject: {fileID: 769026267}
275 | m_Enabled: 1
276 | --- !u!92 &769026270
277 | Behaviour:
278 | m_ObjectHideFlags: 0
279 | m_PrefabParentObject: {fileID: 0}
280 | m_PrefabInternal: {fileID: 0}
281 | m_GameObject: {fileID: 769026267}
282 | m_Enabled: 1
283 | --- !u!20 &769026271
284 | Camera:
285 | m_ObjectHideFlags: 0
286 | m_PrefabParentObject: {fileID: 0}
287 | m_PrefabInternal: {fileID: 0}
288 | m_GameObject: {fileID: 769026267}
289 | m_Enabled: 1
290 | serializedVersion: 2
291 | m_ClearFlags: 1
292 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
293 | m_NormalizedViewPortRect:
294 | serializedVersion: 2
295 | x: 0
296 | y: 0
297 | width: 1
298 | height: 1
299 | near clip plane: 0.3
300 | far clip plane: 1000
301 | field of view: 60
302 | orthographic: 0
303 | orthographic size: 5
304 | m_Depth: -1
305 | m_CullingMask:
306 | serializedVersion: 2
307 | m_Bits: 4294967295
308 | m_RenderingPath: -1
309 | m_TargetTexture: {fileID: 0}
310 | m_TargetDisplay: 0
311 | m_TargetEye: 3
312 | m_HDR: 1
313 | m_AllowMSAA: 1
314 | m_AllowDynamicResolution: 0
315 | m_ForceIntoRT: 0
316 | m_OcclusionCulling: 1
317 | m_StereoConvergence: 10
318 | m_StereoSeparation: 0.022
319 | --- !u!4 &769026272
320 | Transform:
321 | m_ObjectHideFlags: 0
322 | m_PrefabParentObject: {fileID: 0}
323 | m_PrefabInternal: {fileID: 0}
324 | m_GameObject: {fileID: 769026267}
325 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
326 | m_LocalPosition: {x: 0, y: 1, z: -10}
327 | m_LocalScale: {x: 1, y: 1, z: 1}
328 | m_Children: []
329 | m_Father: {fileID: 0}
330 | m_RootOrder: 0
331 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
332 | --- !u!1 &775167930
333 | GameObject:
334 | m_ObjectHideFlags: 0
335 | m_PrefabParentObject: {fileID: 0}
336 | m_PrefabInternal: {fileID: 0}
337 | serializedVersion: 5
338 | m_Component:
339 | - component: {fileID: 775167931}
340 | - component: {fileID: 775167933}
341 | - component: {fileID: 775167932}
342 | m_Layer: 0
343 | m_Name: SpriteHolder1
344 | m_TagString: Untagged
345 | m_Icon: {fileID: 0}
346 | m_NavMeshLayer: 0
347 | m_StaticEditorFlags: 0
348 | m_IsActive: 1
349 | --- !u!224 &775167931
350 | RectTransform:
351 | m_ObjectHideFlags: 0
352 | m_PrefabParentObject: {fileID: 0}
353 | m_PrefabInternal: {fileID: 0}
354 | m_GameObject: {fileID: 775167930}
355 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
356 | m_LocalPosition: {x: 0, y: 0, z: 0}
357 | m_LocalScale: {x: 1, y: 1, z: 1}
358 | m_Children: []
359 | m_Father: {fileID: 1487508546}
360 | m_RootOrder: 0
361 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
362 | m_AnchorMin: {x: 0.5, y: 0.5}
363 | m_AnchorMax: {x: 0.5, y: 0.5}
364 | m_AnchoredPosition: {x: 0, y: 0}
365 | m_SizeDelta: {x: 100, y: 100}
366 | m_Pivot: {x: 0.5, y: 0.5}
367 | --- !u!114 &775167932
368 | MonoBehaviour:
369 | m_ObjectHideFlags: 0
370 | m_PrefabParentObject: {fileID: 0}
371 | m_PrefabInternal: {fileID: 0}
372 | m_GameObject: {fileID: 775167930}
373 | m_Enabled: 1
374 | m_EditorHideFlags: 0
375 | m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
376 | m_Name:
377 | m_EditorClassIdentifier:
378 | m_Material: {fileID: 0}
379 | m_Color: {r: 1, g: 1, b: 1, a: 1}
380 | m_RaycastTarget: 1
381 | m_OnCullStateChanged:
382 | m_PersistentCalls:
383 | m_Calls: []
384 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
385 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
386 | m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
387 | m_Type: 1
388 | m_PreserveAspect: 0
389 | m_FillCenter: 1
390 | m_FillMethod: 4
391 | m_FillAmount: 1
392 | m_FillClockwise: 1
393 | m_FillOrigin: 0
394 | --- !u!222 &775167933
395 | CanvasRenderer:
396 | m_ObjectHideFlags: 0
397 | m_PrefabParentObject: {fileID: 0}
398 | m_PrefabInternal: {fileID: 0}
399 | m_GameObject: {fileID: 775167930}
400 | --- !u!1 &874905657
401 | GameObject:
402 | m_ObjectHideFlags: 0
403 | m_PrefabParentObject: {fileID: 0}
404 | m_PrefabInternal: {fileID: 0}
405 | serializedVersion: 5
406 | m_Component:
407 | - component: {fileID: 874905658}
408 | m_Layer: 0
409 | m_Name: Child6
410 | m_TagString: Untagged
411 | m_Icon: {fileID: 0}
412 | m_NavMeshLayer: 0
413 | m_StaticEditorFlags: 0
414 | m_IsActive: 1
415 | --- !u!4 &874905658
416 | Transform:
417 | m_ObjectHideFlags: 0
418 | m_PrefabParentObject: {fileID: 0}
419 | m_PrefabInternal: {fileID: 0}
420 | m_GameObject: {fileID: 874905657}
421 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
422 | m_LocalPosition: {x: 0, y: 0, z: 0}
423 | m_LocalScale: {x: 1, y: 1, z: 1}
424 | m_Children: []
425 | m_Father: {fileID: 539936832}
426 | m_RootOrder: 5
427 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
428 | --- !u!1 &1148787574
429 | GameObject:
430 | m_ObjectHideFlags: 0
431 | m_PrefabParentObject: {fileID: 0}
432 | m_PrefabInternal: {fileID: 0}
433 | serializedVersion: 5
434 | m_Component:
435 | - component: {fileID: 1148787575}
436 | - component: {fileID: 1148787577}
437 | - component: {fileID: 1148787576}
438 | m_Layer: 0
439 | m_Name: SpriteHolder2
440 | m_TagString: Untagged
441 | m_Icon: {fileID: 0}
442 | m_NavMeshLayer: 0
443 | m_StaticEditorFlags: 0
444 | m_IsActive: 1
445 | --- !u!224 &1148787575
446 | RectTransform:
447 | m_ObjectHideFlags: 0
448 | m_PrefabParentObject: {fileID: 0}
449 | m_PrefabInternal: {fileID: 0}
450 | m_GameObject: {fileID: 1148787574}
451 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
452 | m_LocalPosition: {x: 0, y: 0, z: 0}
453 | m_LocalScale: {x: 1, y: 1, z: 1}
454 | m_Children: []
455 | m_Father: {fileID: 1487508546}
456 | m_RootOrder: 1
457 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
458 | m_AnchorMin: {x: 0.5, y: 0.5}
459 | m_AnchorMax: {x: 0.5, y: 0.5}
460 | m_AnchoredPosition: {x: 0, y: 0}
461 | m_SizeDelta: {x: 100, y: 100}
462 | m_Pivot: {x: 0.5, y: 0.5}
463 | --- !u!114 &1148787576
464 | MonoBehaviour:
465 | m_ObjectHideFlags: 0
466 | m_PrefabParentObject: {fileID: 0}
467 | m_PrefabInternal: {fileID: 0}
468 | m_GameObject: {fileID: 1148787574}
469 | m_Enabled: 1
470 | m_EditorHideFlags: 0
471 | m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
472 | m_Name:
473 | m_EditorClassIdentifier:
474 | m_Material: {fileID: 0}
475 | m_Color: {r: 1, g: 1, b: 1, a: 1}
476 | m_RaycastTarget: 1
477 | m_OnCullStateChanged:
478 | m_PersistentCalls:
479 | m_Calls: []
480 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
481 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
482 | m_Sprite: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0}
483 | m_Type: 0
484 | m_PreserveAspect: 0
485 | m_FillCenter: 1
486 | m_FillMethod: 4
487 | m_FillAmount: 1
488 | m_FillClockwise: 1
489 | m_FillOrigin: 0
490 | --- !u!222 &1148787577
491 | CanvasRenderer:
492 | m_ObjectHideFlags: 0
493 | m_PrefabParentObject: {fileID: 0}
494 | m_PrefabInternal: {fileID: 0}
495 | m_GameObject: {fileID: 1148787574}
496 | --- !u!1 &1487508545
497 | GameObject:
498 | m_ObjectHideFlags: 0
499 | m_PrefabParentObject: {fileID: 0}
500 | m_PrefabInternal: {fileID: 0}
501 | serializedVersion: 5
502 | m_Component:
503 | - component: {fileID: 1487508546}
504 | m_Layer: 0
505 | m_Name: Child1
506 | m_TagString: Untagged
507 | m_Icon: {fileID: 0}
508 | m_NavMeshLayer: 0
509 | m_StaticEditorFlags: 0
510 | m_IsActive: 1
511 | --- !u!4 &1487508546
512 | Transform:
513 | m_ObjectHideFlags: 0
514 | m_PrefabParentObject: {fileID: 0}
515 | m_PrefabInternal: {fileID: 0}
516 | m_GameObject: {fileID: 1487508545}
517 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
518 | m_LocalPosition: {x: 0, y: 0, z: 0}
519 | m_LocalScale: {x: 1, y: 1, z: 1}
520 | m_Children:
521 | - {fileID: 775167931}
522 | - {fileID: 1148787575}
523 | m_Father: {fileID: 539936832}
524 | m_RootOrder: 0
525 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
526 | --- !u!1 &1539683784
527 | GameObject:
528 | m_ObjectHideFlags: 0
529 | m_PrefabParentObject: {fileID: 0}
530 | m_PrefabInternal: {fileID: 0}
531 | serializedVersion: 5
532 | m_Component:
533 | - component: {fileID: 1539683785}
534 | m_Layer: 0
535 | m_Name: Child3
536 | m_TagString: Untagged
537 | m_Icon: {fileID: 0}
538 | m_NavMeshLayer: 0
539 | m_StaticEditorFlags: 0
540 | m_IsActive: 1
541 | --- !u!4 &1539683785
542 | Transform:
543 | m_ObjectHideFlags: 0
544 | m_PrefabParentObject: {fileID: 0}
545 | m_PrefabInternal: {fileID: 0}
546 | m_GameObject: {fileID: 1539683784}
547 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
548 | m_LocalPosition: {x: 0, y: 0, z: 0}
549 | m_LocalScale: {x: 1, y: 1, z: 1}
550 | m_Children: []
551 | m_Father: {fileID: 539936832}
552 | m_RootOrder: 2
553 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
554 | --- !u!1 &1600536897
555 | GameObject:
556 | m_ObjectHideFlags: 0
557 | m_PrefabParentObject: {fileID: 0}
558 | m_PrefabInternal: {fileID: 0}
559 | serializedVersion: 5
560 | m_Component:
561 | - component: {fileID: 1600536898}
562 | m_Layer: 0
563 | m_Name: Child2
564 | m_TagString: Untagged
565 | m_Icon: {fileID: 0}
566 | m_NavMeshLayer: 0
567 | m_StaticEditorFlags: 0
568 | m_IsActive: 1
569 | --- !u!4 &1600536898
570 | Transform:
571 | m_ObjectHideFlags: 0
572 | m_PrefabParentObject: {fileID: 0}
573 | m_PrefabInternal: {fileID: 0}
574 | m_GameObject: {fileID: 1600536897}
575 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
576 | m_LocalPosition: {x: 0, y: 0, z: 0}
577 | m_LocalScale: {x: 1, y: 1, z: 1}
578 | m_Children: []
579 | m_Father: {fileID: 539936832}
580 | m_RootOrder: 1
581 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
582 | --- !u!1 &2125243662
583 | GameObject:
584 | m_ObjectHideFlags: 0
585 | m_PrefabParentObject: {fileID: 0}
586 | m_PrefabInternal: {fileID: 0}
587 | serializedVersion: 5
588 | m_Component:
589 | - component: {fileID: 2125243663}
590 | m_Layer: 0
591 | m_Name: Child5
592 | m_TagString: Untagged
593 | m_Icon: {fileID: 0}
594 | m_NavMeshLayer: 0
595 | m_StaticEditorFlags: 0
596 | m_IsActive: 1
597 | --- !u!4 &2125243663
598 | Transform:
599 | m_ObjectHideFlags: 0
600 | m_PrefabParentObject: {fileID: 0}
601 | m_PrefabInternal: {fileID: 0}
602 | m_GameObject: {fileID: 2125243662}
603 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
604 | m_LocalPosition: {x: 0, y: 0, z: 0}
605 | m_LocalScale: {x: 1, y: 1, z: 1}
606 | m_Children: []
607 | m_Father: {fileID: 539936832}
608 | m_RootOrder: 4
609 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
610 |
--------------------------------------------------------------------------------
/Assets/Sample/Sample.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 23ab8beba3f901c46bb5f9f85fdb4474
3 | timeCreated: 1514215143
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Sample/SampleMemorySnapshot.cs:
--------------------------------------------------------------------------------
1 | using UnityHeapCrawler;
2 | using UnityEditor;
3 | using UnityEditor.Animations;
4 | using UnityEngine;
5 |
6 | namespace Sample
7 | {
8 | public static class SampleMemorySnapshot
9 | {
10 | [MenuItem("Tools/Memory/Customized Heap Snapshot")]
11 | public static void HeapSnapshot()
12 | {
13 | var collector = new HeapSnapshotCollector()
14 | .AddRoot(Game.Instance, "Game.Instance")
15 | .AddRootTypes(typeof(UnitsGroup))
16 | .AddTrackedTypes(typeof(Unit))
17 | .AddTrackedTypes(typeof(Sprite))
18 | .AddTrackedTypes(typeof(Texture));
19 |
20 | var animators = collector.AddUnityRootsGroup
21 | (
22 | "animator-controllers",
23 | "Animator Controllers",
24 | CrawlOrder.SriptableObjects
25 | );
26 | animators.MinItemSize = 1;
27 |
28 | collector.UserRootsSettings.MinItemSize = 1;
29 |
30 | collector.HierarchySettings.MinItemSize = 1;
31 | collector.HierarchySettings.PrintOnlyGameObjects = false;
32 |
33 | collector.PrefabsSettings.MinItemSize = 1;
34 |
35 | collector.UnityObjectsSettings.MinItemSize = 1;
36 |
37 | collector.Start();
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/Assets/Sample/SampleMemorySnapshot.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9c8ebf914c5548b4fb47c7ce8313f11e
3 | timeCreated: 1513952476
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Sample/Unit.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 | using UnityEngine;
3 |
4 | namespace Sample
5 | {
6 | public class Unit
7 | {
8 | public Vector3 Position;
9 |
10 | public float Rotation;
11 |
12 | public int Hp;
13 |
14 | public bool Enemy;
15 |
16 | [CanBeNull]
17 | public Unit Pet;
18 |
19 | public string Name = "Unit name";
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets/Sample/Unit.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d11c8209d27683244b3088f682f66a71
3 | timeCreated: 1513952476
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Sample/UnitComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using JetBrains.Annotations;
3 | using UnityEngine;
4 |
5 | namespace Sample
6 | {
7 | public class UnitComponent : MonoBehaviour
8 | {
9 | [CanBeNull]
10 | [NonSerialized]
11 | public Collider Collider;
12 |
13 | [NotNull]
14 | public UnitVisualSettings VisualSettings = new UnitVisualSettings();
15 |
16 | private void Awake()
17 | {
18 | Collider = GetComponent();
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Assets/Sample/UnitComponent.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4b0d07e451524004e8f724c295091991
3 | timeCreated: 1514197715
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Sample/UnitVisualSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 |
4 | namespace Sample
5 | {
6 | [Serializable]
7 | public class UnitVisualSettings
8 | {
9 | public float Size;
10 | public Color32 Color;
11 | }
12 | }
--------------------------------------------------------------------------------
/Assets/Sample/UnitVisualSettings.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fa97f480633d75547bd2149fcbd3bd11
3 | timeCreated: 1514197715
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Sample/UnitsGroup.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace Sample
4 | {
5 | public class UnitsGroup
6 | {
7 | [NotNull]
8 | public readonly Unit[] Units;
9 |
10 | public UnitsGroup([NotNull] params Unit[] units)
11 | {
12 | Units = units;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Assets/Sample/UnitsGroup.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 88b8dbfec9cf2ce4c825bcb390995041
3 | timeCreated: 1513952476
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a70a79004d7beb84a9f6c61a112f8472
3 | folderAsset: yes
4 | timeCreated: 1513939676
5 | licenseType: Pro
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/CrawlItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using JetBrains.Annotations;
6 | using UnityEngine;
7 | using UnityEngine.Profiling;
8 | using Object = UnityEngine.Object;
9 |
10 | namespace UnityHeapCrawler
11 | {
12 | internal class CrawlItem : IComparable
13 | {
14 | private static int depth;
15 |
16 | [CanBeNull]
17 | public readonly CrawlItem Parent;
18 |
19 | [NotNull]
20 | public readonly object Object;
21 |
22 | [NotNull]
23 | public string Name;
24 |
25 | public long SelfSize;
26 |
27 | public long TotalSize;
28 |
29 | [CanBeNull]
30 | public List Children;
31 |
32 | private bool childrenFiltered;
33 |
34 | internal bool SubtreeUpdated { get; private set; }
35 |
36 | public CrawlItem([CanBeNull] CrawlItem parent, [NotNull] object o, [NotNull] string name)
37 | {
38 | Parent = parent;
39 | Object = o;
40 | Name = name;
41 | }
42 |
43 | public void AddChild([NotNull] CrawlItem child)
44 | {
45 | if (Children == null)
46 | Children = new List();
47 |
48 | Children.Add(child);
49 | }
50 |
51 | public void UpdateSize(SizeMode mode)
52 | {
53 | try
54 | {
55 | SelfSize = 0;
56 | if (mode == SizeMode.Managed || mode == SizeMode.Total)
57 | SelfSize += CalculateSelfManagedSize();
58 | if (mode == SizeMode.Native || mode == SizeMode.Total)
59 | SelfSize += CalculateSelfNativeSize();
60 |
61 | TotalSize = SelfSize;
62 | if (Children == null)
63 | return;
64 |
65 | foreach (var child in Children)
66 | {
67 | child.UpdateSize(mode);
68 | TotalSize += child.TotalSize;
69 | }
70 | Children.Sort();
71 | }
72 | finally
73 | {
74 | TypeStats.RegisterItem(this);
75 | }
76 | }
77 |
78 | public void Cleanup(CrawlSettings crawlSettings)
79 | {
80 | CleanupUnchanged();
81 | CleanupInternal(crawlSettings);
82 | }
83 |
84 | private void CleanupUnchanged()
85 | {
86 | if (Children != null)
87 | {
88 | foreach (var c in Children)
89 | {
90 | c.CleanupUnchanged();
91 | }
92 |
93 | Children.RemoveAll(c => !c.SubtreeUpdated);
94 | SubtreeUpdated = Children.Count > 0;
95 | }
96 |
97 | SubtreeUpdated |= SnapshotHistory.IsNew(Object);
98 | }
99 |
100 | public void CleanupInternal(CrawlSettings crawlSettings)
101 | {
102 | if (!crawlSettings.PrintChildren)
103 | Children = null;
104 |
105 | if (crawlSettings.MaxDepth > 0 && depth >= crawlSettings.MaxDepth)
106 | Children = null;
107 |
108 | if (SnapshotHistory.IsPresent() && SnapshotHistory.IsNew(Object))
109 | Name = Name + " (new)";
110 |
111 | // check for destroyed objects
112 | var unityObject = Object as Object;
113 | if (!ReferenceEquals(unityObject, null) && !unityObject)
114 | {
115 | const string destroyedObjectString = "(destroyed Unity Object)";
116 | if (string.IsNullOrWhiteSpace(Name))
117 | Name = destroyedObjectString;
118 | else
119 | Name = Name + " " + destroyedObjectString;
120 |
121 | Children = null;
122 | }
123 |
124 | if (Children == null)
125 | return;
126 |
127 | if (crawlSettings.PrintOnlyGameObjects)
128 | Children.RemoveAll(c => !(c.Object is GameObject));
129 |
130 | int fullChildrenCount = Children.Count;
131 | if (crawlSettings.MinItemSize > 0)
132 | Children.RemoveAll(c => c.TotalSize < crawlSettings.MinItemSize);
133 | if (crawlSettings.MaxChildren > 0 && Children.Count > crawlSettings.MaxChildren)
134 | Children.RemoveRange(crawlSettings.MaxChildren, Children.Count - crawlSettings.MaxChildren);
135 |
136 | if (Children.Count < fullChildrenCount)
137 | childrenFiltered = true;
138 |
139 | depth++;
140 | foreach (var child in Children)
141 | {
142 | child.CleanupInternal(crawlSettings);
143 | }
144 | depth--;
145 | }
146 |
147 | public void Print([NotNull] StreamWriter w, SizeFormat sizeFormat)
148 | {
149 | for (int i = 0; i < depth; ++i)
150 | w.Write(" ");
151 |
152 | if (!string.IsNullOrWhiteSpace(Name))
153 | {
154 | w.Write(Name);
155 | w.Write(" ");
156 | }
157 |
158 | w.Write("[");
159 | var uo = Object as Object;
160 | if (uo != null)
161 | {
162 | w.Write(uo.name);
163 | w.Write(": ");
164 | w.Write(Object.GetType().GetDisplayName());
165 | w.Write(" (");
166 | w.Write(uo.GetInstanceID());
167 | w.Write(")");
168 | }
169 | else
170 | {
171 | w.Write(Object.GetType().GetDisplayName());
172 | }
173 | w.Write("]");
174 |
175 | w.Write(" ");
176 | w.Write(sizeFormat.Format(TotalSize));
177 | w.WriteLine();
178 |
179 | if (Children != null)
180 | {
181 | depth++;
182 | foreach (var child in Children)
183 | {
184 | child.Print(w, sizeFormat);
185 | }
186 |
187 | if (childrenFiltered && Children.Count > 0)
188 | {
189 | for (int j = 0; j < depth; ++j)
190 | w.Write(" ");
191 |
192 | w.WriteLine("...");
193 | }
194 |
195 | depth--;
196 | }
197 | }
198 |
199 | public string GetRootPath()
200 | {
201 | var items = new List();
202 | var current = this;
203 | do
204 | {
205 | items.Add(current);
206 | current = current.Parent;
207 | } while (current != null);
208 |
209 | items.Reverse();
210 |
211 | var itemNames = items
212 | .Select(i => i.Name)
213 | .ToArray();
214 | return string.Join(".", itemNames);
215 | }
216 |
217 | private long CalculateSelfNativeSize()
218 | {
219 | var uo = Object as Object;
220 | if (uo == null)
221 | return 0L;
222 | return Profiler.GetRuntimeMemorySizeLong(uo);
223 | }
224 |
225 | private long CalculateSelfManagedSize()
226 | {
227 | if (!SnapshotHistory.IsNew(Object))
228 | return 0;
229 |
230 | string str = Object as string;
231 | if (str != null)
232 | {
233 | // string needs special handling
234 | int strSize = 3 * IntPtr.Size + 2;
235 | strSize += str.Length * sizeof(char);
236 | int pad = strSize % IntPtr.Size;
237 | if (pad != 0)
238 | {
239 | strSize += IntPtr.Size - pad;
240 | }
241 | return strSize;
242 | }
243 |
244 |
245 | if (Object.GetType().IsArray)
246 | {
247 | var elementType = Object.GetType().GetElementType();
248 | if (elementType != null && (elementType.IsValueType || elementType.IsPrimitive || elementType.IsEnum))
249 | {
250 | // no overhead for array
251 | return 0;
252 | }
253 | else
254 | {
255 | int arraySize = GetTotalArrayLength((Array)Object);
256 | return IntPtr.Size * arraySize;
257 | }
258 | }
259 |
260 | return TypeData.Get(Object.GetType()).Size;
261 | }
262 |
263 | private static int GetTotalArrayLength(Array val)
264 | {
265 | int sum = val.GetLength(0);
266 | for (int i = 1; i < val.Rank; i++)
267 | {
268 | sum *= val.GetLength(i);
269 | }
270 | return sum;
271 | }
272 |
273 | public int CompareTo(CrawlItem other)
274 | {
275 | if (ReferenceEquals(this, other))
276 | return 0;
277 | if (ReferenceEquals(null, other))
278 | return 1;
279 |
280 | // descending
281 | return other.TotalSize.CompareTo(TotalSize);
282 | }
283 |
284 | public override string ToString()
285 | {
286 | return Object.ToString();
287 | }
288 | }
289 | }
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/CrawlItem.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a744080880debc146a0ecc01c4d68151
3 | timeCreated: 1513952476
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/CrawlOrder.cs:
--------------------------------------------------------------------------------
1 | namespace UnityHeapCrawler
2 | {
3 | ///
4 | /// Order for crawling groups
5 | ///
6 | public enum CrawlOrder
7 | {
8 | UserRoots,
9 | StaticFields,
10 | Hierarchy,
11 | SriptableObjects,
12 | Prefabs,
13 | UnityObjects
14 | }
15 | }
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/CrawlOrder.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2080d21e90a447242ad6576c29fc2a9a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/CrawlSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 | using UnityEngine;
5 |
6 | namespace UnityHeapCrawler
7 | {
8 | ///
9 | /// Output settings for crawling result - memory tree.
10 | ///
11 | public class CrawlSettings
12 | {
13 | [NotNull]
14 | public static IComparer PriorityComparer { get; } = new PriorityRelationalComparer();
15 |
16 | [NotNull]
17 | private static readonly Type[] s_HierarchyTypes =
18 | {
19 | typeof(GameObject),
20 | typeof(Component),
21 | typeof(Material),
22 | typeof(Texture),
23 | typeof(Sprite),
24 | typeof(Mesh)
25 | };
26 |
27 | public bool Enabled = true;
28 |
29 | internal readonly CrawlOrder Order;
30 |
31 | [NotNull]
32 | internal readonly Action RootsCollector;
33 |
34 | internal readonly string Caption;
35 |
36 | ///
37 | /// Resulting memory tree file name.
38 | ///
39 | [NotNull]
40 | public string Filename;
41 |
42 | ///
43 | /// Print children in memory tree. Disable to include only root objects.
44 | ///
45 | public bool PrintChildren = true;
46 |
47 | ///
48 | /// Print only GameObjects in hierarchy mode.
49 | ///
50 | public bool PrintOnlyGameObjects = false;
51 |
52 | ///
53 | /// Follow references to all unity objects or leave them for a later crawling stage
54 | ///
55 | public bool IncludeAllUnityTypes = false;
56 |
57 | ///
58 | /// Follow references to unity objects of specific types
59 | ///
60 | [NotNull]
61 | public List IncludedUnityTypes = new List();
62 |
63 | ///
64 | /// Maximum children depth in memory tree. 0 - infinity.
65 | ///
66 | public int MaxDepth = 0;
67 |
68 | ///
69 | /// Maximum children printed for one object in memory tree. Children are sorted by total size
70 | ///
71 | public int MaxChildren = 10;
72 |
73 | ///
74 | /// Minimum object size to be included in memory tree.
75 | ///
76 | public int MinItemSize = 1024; // bytes
77 |
78 | public CrawlSettings(
79 | [NotNull] string filename,
80 | [NotNull] string caption,
81 | [NotNull] Action rootsCollector,
82 | CrawlOrder order)
83 | {
84 | Filename = filename;
85 | Caption = caption;
86 | RootsCollector = rootsCollector;
87 | Order = order;
88 | }
89 |
90 | internal bool IsUnityTypeAllowed(Type type)
91 | {
92 | if (IncludeAllUnityTypes)
93 | return true;
94 |
95 | foreach (var allowedType in IncludedUnityTypes)
96 | {
97 | if (allowedType.IsAssignableFrom(type))
98 | {
99 | return true;
100 | }
101 | }
102 |
103 | return false;
104 | }
105 |
106 | [NotNull]
107 | public static CrawlSettings CreateUserRoots([NotNull] Action objectsProvider)
108 | {
109 | return new CrawlSettings("user-roots", "User Roots", objectsProvider, CrawlOrder.UserRoots)
110 | {
111 | MaxChildren = 0
112 | };
113 | }
114 |
115 | [NotNull]
116 | public static CrawlSettings CreateStaticFields([NotNull] Action objectsProvider)
117 | {
118 | return new CrawlSettings("static-fields", "Static Roots", objectsProvider, CrawlOrder.StaticFields)
119 | {
120 | MaxDepth = 1
121 | };
122 | }
123 |
124 | [NotNull]
125 | public static CrawlSettings CreateHierarchy([NotNull] Action objectsProvider)
126 | {
127 | return new CrawlSettings("hierarchy", "Hierarchy", objectsProvider, CrawlOrder.Hierarchy)
128 | {
129 | PrintOnlyGameObjects = true,
130 | MaxChildren = 0,
131 | IncludedUnityTypes = new List(s_HierarchyTypes)
132 | };
133 | }
134 |
135 | [NotNull]
136 | public static CrawlSettings CreateScriptableObjects([NotNull] Action objectsProvider)
137 | {
138 | return new CrawlSettings("scriptable_objects", "Scriptable Objects", objectsProvider, CrawlOrder.UnityObjects)
139 | {
140 | IncludeAllUnityTypes = true
141 | };
142 | }
143 |
144 | [NotNull]
145 | public static CrawlSettings CreatePrefabs([NotNull] Action objectsProvider)
146 | {
147 | return new CrawlSettings("prefabs", "Prefabs", objectsProvider, CrawlOrder.Prefabs)
148 | {
149 | PrintOnlyGameObjects = true,
150 | MaxChildren = 0,
151 | IncludedUnityTypes = new List(s_HierarchyTypes)
152 | };
153 | }
154 |
155 | [NotNull]
156 | public static CrawlSettings CreateUnityObjects([NotNull] Action objectsProvider)
157 | {
158 | return new CrawlSettings("unity_objects", "Unity Objects", objectsProvider, CrawlOrder.UnityObjects);
159 | }
160 |
161 | public override string ToString()
162 | {
163 | return $"Crawl Settings [{Caption}, {Filename}]";
164 | }
165 |
166 | private sealed class PriorityRelationalComparer : IComparer
167 | {
168 | public int Compare(CrawlSettings x, CrawlSettings y)
169 | {
170 | if (ReferenceEquals(x, y)) return 0;
171 | if (ReferenceEquals(null, y)) return 1;
172 | if (ReferenceEquals(null, x)) return -1;
173 | return x.Order.CompareTo(y.Order);
174 | }
175 | }
176 | }
177 | }
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/CrawlSettings.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6f5f192c8aaf4b14c832690493d6b9bf
3 | timeCreated: 1514195617
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/UnityHeapCrawler/HeapSnapshotCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using JetBrains.Annotations;
7 | using UnityEditor;
8 | using UnityEngine;
9 | using UnityEngine.Profiling;
10 | using Object = UnityEngine.Object;
11 |
12 | namespace UnityHeapCrawler
13 | {
14 | ///
15 | /// Tool for crawling mono heap and collecting memory usage.
16 | ///
17 | /// 1. Analyze managed memory consumption prior to reducing it
18 | /// 2. Locate managed memory leaks.
19 | ///
20 | ///
21 | public class HeapSnapshotCollector
22 | {
23 | ///
24 | /// for user defined roots.
25 | ///
26 | /// Modify them after construction to change output format or disable crawling.
27 | /// Be careful when reducing filtering - large crawl trees will affect memory consumption.
28 | ///
29 | ///
30 | [NotNull]
31 | public readonly CrawlSettings UserRootsSettings;
32 |
33 | ///
34 | /// for static fields in all types.
35 | ///
36 | /// Modify them after construction to change output format or disable crawling.
37 | /// Be careful when reducing filtering - large crawl trees will affect memory consumption.
38 | ///
39 | ///
40 | [NotNull]
41 | public readonly CrawlSettings StaticFieldsSettings;
42 |
43 | ///
44 | /// for GameObjects in scene hierarchy.
45 | ///
46 | /// Modify them after construction to change output format or disable crawling.
47 | /// Be careful when reducing filtering - large crawl trees will affect memory consumption.
48 | ///
49 | ///
50 | [NotNull]
51 | public readonly CrawlSettings HierarchySettings;
52 |
53 | ///
54 | /// for all ScriptableObjects.
55 | ///
56 | /// Modify them after construction to change output format or disable crawling.
57 | /// Be careful when reducing filtering - large crawl trees will affect memory consumption.
58 | ///
59 | ///
60 | [NotNull]
61 | public readonly CrawlSettings ScriptableObjectsSettings;
62 |
63 | ///
64 | /// for all loaded Prefabs.
65 | ///
66 | /// Modify them after construction to change output format or disable crawling.
67 | /// Be careful when reducing filtering - large crawl trees will affect memory consumption.
68 | ///
69 | ///
70 | [NotNull]
71 | public readonly CrawlSettings PrefabsSettings;
72 |
73 | ///
74 | /// for all other Unity objects (Texture, Material, etc).
75 | ///
76 | /// Modify them after construction to change output format or disable crawling.
77 | /// Be careful when reducing filtering - large crawl trees will affect memory consumption.
78 | ///
79 | ///
80 | [NotNull]
81 | public readonly CrawlSettings UnityObjectsSettings;
82 |
83 | ///
84 | /// Only show new objects (compared to previous snapshot) in all reports
85 | ///
86 | /// Useful to find memory leaks
87 | ///
88 | ///
89 | public bool DifferentialMode = true;
90 |
91 | ///
92 | /// Which size estimations are used
93 | ///
94 | /// - Managed - heap estimation
95 | /// - Native - native size estimation for Unity objects
96 | /// - Total - Managed + Native
97 | ///
98 | ///
99 | public SizeMode SizeMode = SizeMode.Managed;
100 |
101 | #region PrivateFields
102 |
103 | [NotNull]
104 | private readonly List crawlOrder = new List();
105 |
106 | [NotNull]
107 | private readonly List customRoots = new List();
108 |
109 | [NotNull]
110 | private readonly List rootTypes = new List();
111 |
112 | [NotNull]
113 | private readonly List forbiddenTypes = new List();
114 |
115 | [NotNull]
116 | private readonly List staticTypes = new List();
117 |
118 | [NotNull]
119 | private readonly List trackedTypes = new List();
120 |
121 | [NotNull]
122 | private readonly HashSet