内容简介:Unity3D研究院编辑器之ManagedStaticReferences()静态引用(二十九)
Unity的Profiler可以看出来内存,但是遇到ManagedStaticReferences()估计大家都跪了。因为这个资源被静态引用了,然后我们并不知道它被哪里静态引用了。
我想了个办法,可以通过反射来查询它。先讲一下原理
1.反射dll
2.遍历所有的.cs 取出所有带static的属性。
3.对static下的所有属性以及子属性进行深度遍历,最终即可得出来被静态引用的资源。
如下代码所示,运行环境unity5.2.2
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Reflection; using System; using System.Text; public partial class ReportAsset{ [MenuItem("Tools/Report/脚本Static引用")] static void StaticRef () { //静态引用 LoadAssembly ("Assembly-CSharp-firstpass"); LoadAssembly ("Assembly-CSharp"); } static void LoadAssembly(string name) { Assembly assembly = null; try { assembly = Assembly.Load(name); } catch (Exception ex) { Debug.LogWarning (ex.Message); } finally{ if (assembly != null) { foreach (Type type in assembly.GetTypes()) { try { HashSet<string> assetPaths = new HashSet<string>(); FieldInfo[] listFieldInfo = type.GetFields (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); foreach (FieldInfo fieldInfo in listFieldInfo) { if (!fieldInfo.FieldType.IsValueType) { SearchProperties (fieldInfo.GetValue (null),assetPaths); } } if (assetPaths.Count > 0) { StringBuilder sb = new StringBuilder (); sb.AppendFormat ("{0}.cs\n", type.ToString ()); foreach (string path in assetPaths) { sb.AppendFormat ("\t{0}\n", path); } Debug.LogError (sb.ToString ()); } } catch(Exception ex){ Debug.LogWarning (ex.Message); } } } } } static HashSet<string> SearchProperties(object obj,HashSet<string> assetPaths) { if (obj != null) { if (obj is UnityEngine.Object) { UnityEngine.Object[]depen = EditorUtility.CollectDependencies (new UnityEngine.Object[]{ obj as UnityEngine.Object }); foreach (var item in depen) { string assetPath = AssetDatabase.GetAssetPath (item); if (!string.IsNullOrEmpty (assetPath)) { if (!assetPaths.Contains (assetPath)) { assetPaths.Add (assetPath); } } } } else if (obj is IEnumerable) { foreach (object child in (obj as IEnumerable)) { SearchProperties (child,assetPaths); } }else if (obj is System.Object) { if (!obj.GetType ().IsValueType) { FieldInfo[] fieldInfos = obj.GetType ().GetFields (); foreach (FieldInfo fieldInfo in fieldInfos) { object o = fieldInfo.GetValue (obj); if (o != obj) { SearchProperties (fieldInfo.GetValue (obj),assetPaths); } } } } } return assetPaths; } }
如下图所示,静态引用已经查出来了。
问题:
1.这个脚本查不出 lua 里的静态引用。lua可以遍历G里的所有table表,和上面执行类型的操作就可以查出来。
2.如果想定向查询,比如专门查某一个资源在内存中哪里被引用,也和上面算法差不多改改就可以。
3.Unity在Editor下的Profiler其实是非常不准确的,因为自己在Project视图中选择一些资源unity也会记录在Profiler中,并且没办法完全清除。如果想测试内存,可以打一个pc包在连上Profiler在看即可。
最后,如果大家有更好的方法,欢迎再下面给我留言,我们一起讨论~
- 本文固定链接: http://www.xuanyusong.com/archives/4390
- 转载请注明:雨松MOMO 于雨松MOMO程序研究院 发表
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
捐 赠 如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Unity3D研究院编辑器之ManagedStaticReferences()静态引用(二十九)
- 我做编辑器这些年:钉钉文档编辑器的前世今生
- 有爱编辑器 1.7.1 发布,mysql 编辑器 GUI
- 小书匠编辑器 6.0.0 发布,好用的 Markdown 编辑器
- 小书匠编辑器 6.0.0 发布,好用的 Markdown 编辑器
- 静态库遇到静态库
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。