DebuggerComponent.RuntimeMemoryInformationWindow.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //------------------------------------------------------------
  2. // Game Framework v3.x
  3. // Copyright © 2013-2017 Jiang Yin. All rights reserved.
  4. // Homepage: http://gameframework.cn/
  5. // Feedback: mailto:i@jiangyin.me
  6. //------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using UnityEngine;
  10. #if UNITY_5_5_OR_NEWER
  11. using UnityEngine.Profiling;
  12. #endif
  13. namespace UnityGameFramework.Runtime
  14. {
  15. public partial class DebuggerComponent
  16. {
  17. private sealed partial class RuntimeMemoryInformationWindow<T> : ScrollableDebuggerWindowBase where T : UnityEngine.Object
  18. {
  19. private const int ShowSampleCount = 300;
  20. private DateTime m_SampleTime = DateTime.MinValue;
  21. private long m_SampleSize = 0;
  22. private long m_DuplicateSampleSize = 0;
  23. private int m_DuplicateSimpleCount = 0;
  24. private List<Sample> m_Samples = new List<Sample>();
  25. protected override void OnDrawScrollableWindow()
  26. {
  27. string typeName = typeof(T).Name;
  28. GUILayout.Label(string.Format("<b>{0} Runtime Memory Information</b>", typeName));
  29. GUILayout.BeginVertical("box");
  30. {
  31. if (GUILayout.Button(string.Format("Take Sample for {0}", typeName), GUILayout.Height(30f)))
  32. {
  33. TakeSample();
  34. }
  35. if (m_SampleTime <= DateTime.MinValue)
  36. {
  37. GUILayout.Label(string.Format("<b>Please take sample for {0} first.</b>", typeName));
  38. }
  39. else
  40. {
  41. if (m_DuplicateSimpleCount > 0)
  42. {
  43. GUILayout.Label(string.Format("<b>{0} {1}s ({2}) obtained at {3}, while {4} {1}s ({5}) might be duplicated.</b>", m_Samples.Count.ToString(), typeName, GetSizeString(m_SampleSize), m_SampleTime.ToString("yyyy-MM-dd HH:mm:ss"), m_DuplicateSimpleCount.ToString(), GetSizeString(m_DuplicateSampleSize)));
  44. }
  45. else
  46. {
  47. GUILayout.Label(string.Format("<b>{0} {1}s ({2}) obtained at {3}.</b>", m_Samples.Count.ToString(), typeName, GetSizeString(m_SampleSize), m_SampleTime.ToString("yyyy-MM-dd HH:mm:ss")));
  48. }
  49. if (m_Samples.Count > 0)
  50. {
  51. GUILayout.BeginHorizontal();
  52. {
  53. GUILayout.Label(string.Format("<b>{0} Name</b>", typeName));
  54. GUILayout.Label("<b>Type</b>", GUILayout.Width(240f));
  55. GUILayout.Label("<b>Size</b>", GUILayout.Width(80f));
  56. }
  57. GUILayout.EndHorizontal();
  58. }
  59. int count = 0;
  60. for (int i = 0; i < m_Samples.Count; i++)
  61. {
  62. GUILayout.BeginHorizontal();
  63. {
  64. GUILayout.Label(m_Samples[i].Highlight ? string.Format("<color=yellow>{0}</color>", m_Samples[i].Name) : m_Samples[i].Name);
  65. GUILayout.Label(m_Samples[i].Highlight ? string.Format("<color=yellow>{0}</color>", m_Samples[i].Type) : m_Samples[i].Type, GUILayout.Width(240f));
  66. GUILayout.Label(m_Samples[i].Highlight ? string.Format("<color=yellow>{0}</color>", GetSizeString(m_Samples[i].Size)) : GetSizeString(m_Samples[i].Size), GUILayout.Width(80f));
  67. }
  68. GUILayout.EndHorizontal();
  69. count++;
  70. if (count >= ShowSampleCount)
  71. {
  72. break;
  73. }
  74. }
  75. }
  76. }
  77. GUILayout.EndVertical();
  78. }
  79. private void TakeSample()
  80. {
  81. m_SampleTime = DateTime.Now;
  82. m_SampleSize = 0L;
  83. m_DuplicateSampleSize = 0L;
  84. m_DuplicateSimpleCount = 0;
  85. m_Samples.Clear();
  86. T[] samples = Resources.FindObjectsOfTypeAll<T>();
  87. for (int i = 0; i < samples.Length; i++)
  88. {
  89. long sampleSize = 0L;
  90. #if UNITY_5_6_OR_NEWER
  91. sampleSize = Profiler.GetRuntimeMemorySizeLong(samples[i]);
  92. #else
  93. sampleSize = Profiler.GetRuntimeMemorySize(samples[i]);
  94. #endif
  95. m_SampleSize += sampleSize;
  96. m_Samples.Add(new Sample(samples[i].name, samples[i].GetType().Name, sampleSize));
  97. }
  98. m_Samples.Sort(SampleComparer);
  99. for (int i = 1; i < m_Samples.Count; i++)
  100. {
  101. if (m_Samples[i].Name == m_Samples[i - 1].Name && m_Samples[i].Type == m_Samples[i - 1].Type && m_Samples[i].Size == m_Samples[i - 1].Size)
  102. {
  103. m_Samples[i].Highlight = true;
  104. m_DuplicateSampleSize += m_Samples[i].Size;
  105. m_DuplicateSimpleCount++;
  106. }
  107. }
  108. }
  109. private string GetSizeString(long size)
  110. {
  111. if (size < 1024L)
  112. {
  113. return string.Format("{0} Bytes", size.ToString());
  114. }
  115. if (size < 1024L * 1024L)
  116. {
  117. return string.Format("{0} KB", (size / 1024f).ToString("F2"));
  118. }
  119. if (size < 1024L * 1024L * 1024L)
  120. {
  121. return string.Format("{0} MB", (size / 1024f / 1024f).ToString("F2"));
  122. }
  123. if (size < 1024L * 1024L * 1024L * 1024L)
  124. {
  125. return string.Format("{0} GB", (size / 1024f / 1024f / 1024f).ToString("F2"));
  126. }
  127. return string.Format("{0} TB", (size / 1024f / 1024f / 1024f / 1024f).ToString("F2"));
  128. }
  129. private int SampleComparer(Sample a, Sample b)
  130. {
  131. int result = b.Size.CompareTo(a.Size);
  132. if (result != 0)
  133. {
  134. return result;
  135. }
  136. result = a.Type.CompareTo(b.Type);
  137. if (result != 0)
  138. {
  139. return result;
  140. }
  141. return a.Name.CompareTo(b.Name);
  142. }
  143. }
  144. }
  145. }