执行完后 通过.net 内存监视器 发现 lstData 内所有的对象都没有释放。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;
using System.Runtime.InteropServices;namespace TestEmit {
class Program {
static void Main(string[] args) {
Test t = new Test();
t.t();
GC.Collect();
Console.ReadLine();
}
}
public class Test {
public void t() {
var r = SetPropertyValue(typeof(TestClass), "Name");
List<object> lstData = new List<object>();
for (int i = 0; i < 1000000; i++) {
TestClass t = new TestClass();
r.Invoke(null, new object[]{t,"AAA" + i });
lstData.Add(t);
}
}
//public delegate void SetPropertyDelegate(object obj, object m_Value);
public static DynamicMethod SetPropertyValue(Type oType, string propertyName) {
PropertyInfo pi = oType.GetProperty(propertyName); if (pi != null) {
string methodName = pi.Name; DynamicMethod dm = new DynamicMethod("XXXXX_" + methodName,typeof(void),
new Type[] { typeof(object), typeof(object) }, pi.Module, true);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, pi.GetSetMethod(true), null); if (pi.PropertyType.IsValueType) {
il.Emit(OpCodes.Unbox_Any, pi.PropertyType);
}
il.Emit(OpCodes.Ret);
return dm;
//return (SetPropertyDelegate)dm.CreateDelegate(typeof(SetPropertyDelegate));
}
else {
throw new NullReferenceException("exception");
}
}
}
public class TestClass {
public string Name { get; set; }
public string Code { get; set; }
public string Address { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;
using System.Runtime.InteropServices;namespace TestEmit {
class Program {
static void Main(string[] args) {
Test t = new Test();
t.t();
GC.Collect();
Console.ReadLine();
}
}
public class Test {
public void t() {
var r = SetPropertyValue(typeof(TestClass), "Name");
List<object> lstData = new List<object>();
for (int i = 0; i < 1000000; i++) {
TestClass t = new TestClass();
r.Invoke(null, new object[]{t,"AAA" + i });
lstData.Add(t);
}
}
//public delegate void SetPropertyDelegate(object obj, object m_Value);
public static DynamicMethod SetPropertyValue(Type oType, string propertyName) {
PropertyInfo pi = oType.GetProperty(propertyName); if (pi != null) {
string methodName = pi.Name; DynamicMethod dm = new DynamicMethod("XXXXX_" + methodName,typeof(void),
new Type[] { typeof(object), typeof(object) }, pi.Module, true);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, pi.GetSetMethod(true), null); if (pi.PropertyType.IsValueType) {
il.Emit(OpCodes.Unbox_Any, pi.PropertyType);
}
il.Emit(OpCodes.Ret);
return dm;
//return (SetPropertyDelegate)dm.CreateDelegate(typeof(SetPropertyDelegate));
}
else {
throw new NullReferenceException("exception");
}
}
}
public class TestClass {
public string Name { get; set; }
public string Code { get; set; }
public string Address { get; set; }
}
}
GC.WaitForPendingFinalizers();两个一起调用,只调用GC.Collect();垃圾收集器的动作是没那么快的,你需要等待它完成该线程上的清理工作。
lstData 中所有对象没有被释放,应该还存在被引用。
初步分析下来应该是DynamicMethod 创建的 assembly 没有被释放。
但不知道怎么解决?
但我想把 DynamicMethod(无法系列化) 传出来,这样调用性能会快一些,如果每调用一个属性都需要创建一个新的DynamicMethod倒不如直接用反射来的直接一点。
不可能的~~~你用windbg 看看 :)