日期:2014-05-18 浏览次数:20567 次
/// <summary> /// 查询所有菜品 【方法A】 /// </summary> /// <returns>返回[IList]</returns> public static IList<FoodInfo> GetAllFood() { IList<FoodInfo> listFood = new List<FoodInfo>(); ; FoodInfo food= null;//1.创建 string sql = "select FID,F_Pic,F_Desc from FoodInfo order by F_SendTime desc,FID desc"; OleDbDataReader dr=SqlHelper.GetReader(sql) while (dr.Read()) { food= new FoodInfo();//2.实例化 food.FID = Convert.ToInt32(dr[0]); food.F_Pic = dr[1].ToString(); food.F_Desc = dr[2].ToString(); listFood.Add(food); } return listCus; }
/// <summary> /// 查询所有菜品 【方法B】 /// </summary> /// <returns>返回[IList]</returns> public static IList<FoodInfo> GetAllFood() { IList<FoodInfo> listFood = new List<FoodInfo>(); ; string sql = "select FID,F_Pic,F_Desc from FoodInfo order by F_SendTime desc,FID desc"; OleDbDataReader dr=SqlHelper.GetReader(sql) while (dr.Read()) { FoodInfo food == new FoodInfo();//1.创建,并且实例化 food.FID = Convert.ToInt32(dr[0]); food.F_Pic = dr[1].ToString(); food.F_Desc = dr[2].ToString(); listFood.Add(food); } return listCus; }
堆栈的内存分配机制 对于值类型,一般创建在线程堆栈上。但是值类型作为实例成员的一部分或发生装箱时,值类型 是存储在托管堆上的。 对于分配在堆栈上的局部变量来说,操作系统维护一个堆栈指针来指向下一个自由空间的地址, 并且堆栈的内存地址是由高位到低位向下填充。 托管堆的内存分配机制: 引用类型的实例分配于托管堆上,而线程栈是对象生命周期开始的地方。32位处理器来说,应用 程序完成进程初始化后,CLR将在进程的可用地址空间上分配一块保留的地址空间,它是进程( 每个进程可使用4GB)中可用地址空间上的一块内存区域,但并不对应于任何物理内存,这块地址 空间即是托管堆。 托管堆可划分不同区域:重要的包括垃圾回收堆(GC Heap)和加载堆(Loader Heap),GC Heap 用于存储对象实例,受GC管理;Loader Heap最重要的信息就是和元数据相关的信息,也就是Type 对象,每个Type在Loader Heap上体现为一个方法表(Method Table,创建于编译时期,主要包含类 型的特征信息、实现的接口数目等),Loader Heap不受GC控制,其生命周期是从创建到AppDomain卸载 FoodInfo food= null;//声明了一个引用类型的变量food,这不是创建!!! 它仅是一个引用(或指针),保村在线程的堆栈上,占4Byte的内存,用于保存FoodInfo对象的有 效地址,执行过程是线程栈上的分配过程。此时food为指向任何有效实例,手动初始化为null,试 图对food的任何操作将抛出NullReferenceException的异常; while { 接着 food= new FoodInfo();通过new操作执行对象创建,该操作对应IL中的newobj指令,执行过程 如下: (a) CLR按照继承关系进行递归搜素,找到System.Object类型,并返回字节总数total(根据你的成员及附加成员的总字节数计算)。 (b) CLR在当前AppDomain对应的托管堆上搜素,找到一个连续未使用的total字节的连续空间 并为其分配地址。注:堆得分配是向高地址扩展,和栈分配时相反的 (c) 如果分配空间时发现内存不足,GC将启动垃圾收集操作来回收垃圾对象所占的内存。 (d)调用构造器,进行初始化操作,完成创建。 (e) 引用指向分配的托管堆地址 } 这个过程重复利用了一个指针,每次循环的时候都是改变这个指针指向的位置而已 while (dr.Read()) { FoodInfo food == new FoodInfo(); 这个过程先执都会在线程栈上创建一个新的引用,然后(a)(b)(c)(d),然后将新的引用指向分配的托管堆空间 } 同时,二者的声明的范围不一样