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

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

内容简介: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块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

Pro JavaScript Design Patterns

Pro JavaScript Design Patterns

Dustin Diaz、Ross Harmes / Apress / 2007-12-16 / USD 44.99

As a web developer, you’ll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power......一起来看看 《Pro JavaScript Design Patterns》 这本书的介绍吧!

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具