Unity3D研究院编辑器之ManagedStaticReferences()静态引用(二十九)

栏目: 后端 · 发布时间: 6年前

内容简介: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;
 }
 
}

如下图所示,静态引用已经查出来了。

Unity3D研究院编辑器之ManagedStaticReferences()静态引用(二十九)

问题:

1.这个脚本查不出 lua 里的静态引用。lua可以遍历G里的所有table表,和上面执行类型的操作就可以查出来。

2.如果想定向查询,比如专门查某一个资源在内存中哪里被引用,也和上面算法差不多改改就可以。

3.Unity在Editor下的Profiler其实是非常不准确的,因为自己在Project视图中选择一些资源unity也会记录在Profiler中,并且没办法完全清除。如果想测试内存,可以打一个pc包在连上Profiler在看即可。

最后,如果大家有更好的方法,欢迎再下面给我留言,我们一起讨论~

雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!

最后编辑:

作者:雨松MOMO

专注移动互联网,Unity3D游戏开发

站内专栏 QQ交谈 腾讯微博 新浪微博

捐 赠 如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Lighttpd

Lighttpd

Andre Bogus / Packt Publishing / 2008-10 / 39.99

This is your fast guide to getting started and getting inside the Lighttpd web server. Written from a developer's perspective, this book helps you understand Lighttpd, and get it set up as securely an......一起来看看 《Lighttpd》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试