首页 新闻 会员 周边

CLR和垃圾回收机制球赐教

0
[待解决问题]

11、CLR公共语言运行时:
一、将源代码编译成托管模块
源代码编译过程:代码源文件》对应编译器》托管模块(中间语言和元数据)
托管模块是一个标准的PE(Portable Executable,可移植执行体)文件 托管模块组成部分:
PE32或者PE32+头:标示文件能在Windows上运行的版本,例如Windows的32位或者64位版本上运行,CPU架构(anycpu、x86等等)
CLR头:包含使这个模块成为托管模块的信息。例如包含CLR版本信息,一些标志(托管模块入口方法的标志(如果模块是CUI或GUI(Console、

Graphics user interface执行体)),元数据的大小和偏移量
元数据:包含两张元数据表,一张描述源代码中定义的类型和成员,另外一张表描述源代码引用的类型和成员。元数据使用关联着包含IL代码的

文件。
IL代码:IL是与CPU无关的机器语言,比大多数CPU机器语言都高级,能访问和操作对象类型,捕获和处理异常

二、将托管模块合并成程序集
说明:CLR实际不合模块一起工作,而是和程序集一起工作,所以需要将模块添加到程序集中。过程如下:
托管模块(多个)+资源文件(多个) =》 将多个托管模块和资源文件合并成程序集的工具(C#编译器) =》 程序集(清单:描述程序集中的

模块,(托管模块多个、资源文件多个)

程序集:程序集是一个或多个类型定义文件及资源文件的集合,在程序集的所有文件中有一个文件容纳了清单。CLR总是加载包含“清单”元数

据的文件。一般情况下程序集就只有一个包含清单的文件。

IL代码编译成本地代码的过程:CLR的JIT编译器的职责
例子:
static void main(){
 Console.WriteLine("Hello");
 Console.WriteLine("GoodBye");
}
过程分析:
JITCompiler函数执行过程{
 1、在main函数执行前检查main方法代码引用的所有类型,找到实现Console.WriteLine的程序集的元数据
 2、根据元数据分配内存,元数据的每一个方法都对应一个记录项(Entry),例如包含Console.WriteLine方法的记录项
 3、JITCompiler从元数据中查找调用方法的IL代码并编译成本地代码。本地代码保存到动态内存中
 4、找到刚才被调用方法的记录项的地址,让他直接指向刚才编译好的本地代码的内存地址
 5、JITCompiler跳转到刚才编译好的内存块中的代码,然后执行。执行后返回到Main中代码继续执行。
}
当第二次执行WriteLine方法时,会直接跳转到内存块的代码,完全跳过JITCompiler函数。
其他功能:代码的优化也在JIT时执行、安全性验证(例如参数数量、参数类型)

12、垃圾回收机制:
一、从托管堆分配资源:
1、进程初始化时,CLR保留一块连续完整的地址空间即托管堆。托管堆维护着一个指针NextObjPtr指向下一个对象在堆中的地址。
2、创建对象时执行newobj指令(相当于new操作)。(1)计算类型字段所需字节数(2)加上对象的开销所需字节数(两个开销字段:一个类型

对象指针,一个同

步块索引)(3)CLR检查指向的托管堆区域是否能放得下对象,能则放入对象。接着调用对象的实例化构造器,newobj指令放回创建对象的地址

(说明:A a = new

A(),这里创建的对象new A()的地址返回给a实例),在返回之前NextObjPtr指针的值加上创建对象所占据的字节数,NextObjPrt指向一个新地址


3、怎样确保在NextObjPtr指向的地址上有足够的空间能创建对象,这就需要垃圾回收机制了。
二、垃圾回收方法:
1)、Finalize终结器或析构器:释放类型中使用的本地资源,当垃圾回收时Finalize会自动执行。
过程:实现Finalize的对象在垃圾回收时不能立即回收。这些实现了Finalize的对象会在终结列表中被标记,当垃圾回收时当一个对象不可达时

如果没有标记在终结器中则直接回收,如果标记在终结列表中则不能马上被回收,而是把这些对象移到freachable(Finalize reachable)列表

中,然后由特殊的高优先级的CLR线程专门执行Finalize方法。Finalize方法执行后,下次垃圾回收才能真正释放该对象。

问题补充:

完成:T-SQL语句学习(一) - xuxu8511 - 博客园
 SQL语句之语法汇总
 SQL触发器实例讲解
 黑马学习日记_SQL基础
 sql server 2008学习
计划中:

--视图
CREATE VIEW Student_View
AS
 SELECT SID, SNAME, SAGE FROM Students


--索引
CREATE UNIQUE INDEX Student_Index
ON dbo.Students(SID ASC)

DROP INDEX  Student_Index

--触发器
CREATE TRIGGER AGE_TRIGGER ON dbo.Students
FOR  INSERT , UPDATE
AS
 if(UPDATE(SAGE))
 BEGIN
  UPDATE Students SET Students.SAGE = 15 FROM INSERTED WHERE Students.SID = INSERTED.SID AND INSERTED.SAGE < 15
 END

--通配符
通配符_,单个字符;通配符%,零或多个字符

--UNION
union会将重复数据合并;union all不考虑重复数据
1)union合并会消除重复项,而union  all不考虑重复,会将数据完全合并累加

2) union时,需要两个table中要union的结果集中,具有相同的列数,且列类型要相容才可以union

3)union需要进行重复值扫描,效率比较低,所以如果不是确定要进行重复行合并,那么就使用union all

--数字函数
绝对值 abs(-3.1415);
舍入到最大整数 ceiling(3.2); 
舍入到最小整数 floor(3.2); 
四舍五入到“离半径最近的数”、后面的3即保留三位小数 round(3.1413,3);      
--字符串函数
字符串长度 select len('abcd');
转小写 select lower('abcdEMN');           
转大写 select upper('abcdEMN');
去左空格 select ltrim('   ss   ');         
去右空格 select rtrim('   ss   ');
去左右空格 select rtrim(ltrim('   ss   '));
select substring('abcdef',3,3);     --结果:cde;格式:substring(string,startIndex,length)

--日期函数
当前时间 getdate();
分别获取年/月/日 select DatePart(year,getdate()),DatePart(month,getdate()),DatePart(day,getdate());
在当前日期运算 DateAdd(datePart,number,date);
日期差值 DateDiff(datePart,startDate,endDate);
--类型装换
select cast('123'as int);
select cast('2008-08-08' as datetime);
select convert(datetime,'2009-09-09');
select convert(varchar(50),123);

--CASE语句
SELECT SNAME, SFirstC,
(
 CASE
  WHEN SFirstC >= 80 THEN '良'
  WHEN SFirstC >=70 THEN '中'
  WHEN SFirstC >= 60 THEN '及格'
  ELSE '不及格'
 END
)
FROM dbo.Students

--添加主键
ALTER TABLE dbo.Teacher
--ADD PRIMARY KEY(TNAME)
ADD CONSTRAINT pk_Teacher_TNAME PRIMARY KEY(TNAME)

--添加外键
ALTER TABLE Course
ADD CONSTRAINT Course_TeacherName FOREIGN KEY(CTeacher) REFERENCES dbo.Teacher(TNAME) ON DELETE CASCADE ON UPDATE CASCADE

ALTER TABLE Course
DROP CONSTRAINT Course_TeacherName
--添加Check约束
ALTER TABLE dbo.Teacher
ADD CONSTRAINT ck_Teacher_tage CHECK(TAGE > 0)
--添加Defaul约束
ALTER TABLE dbo.Teacher
ADD CONSTRAINT default_Teacher_ID DEFAULT 0 FOR ID

--存储过程
ALTER PROCEDURE procedure_StudentsCount
@COUNT NVARCHAR(20) OUTPUT
--ENCRYPTION加密,RECOMPILE每次执行都重新编译
WITH ENCRYPTION,RECOMPILE
AS
  SELECT @COUNT = COUNT(*) FROM dbo.Students

--执行存储过程
DECLARE @COUNT INT
EXEC dbo.procedure_StudentsCount @COUNT = @COUNT OUTPUT
PRINT '总人数:' + CONVERT(VARCHAR, @COUNT)

--内连接、外连接(左连接、有链接、完整外连接)
内连接inner join or join: select   a.*,b.*   from   a   inner   join[or join]   b     on   a.id=b.parent_id  
左连接left outer join[or left join]:select   a.*,b.*   from   a   left   join   b     on   a.id=b.parent_id  
右连接right outer join[or right join:select   a.*,b.*   from   a   right   join   b     on   a.id=b.parent_id  
完整外连接full join:select   a.*,b.*   from   a   full   join   b     on   a.id=b.parent_id  

 


  

heavi的主页 heavi | 初学一级 | 园豆:195
提问于:2012-06-30 17:47
< >
分享
所有回答(1)
0

你是在自己回答自己的问题吗?

jerry-Tom | 园豆:4077 (老鸟四级) | 2012-07-02 10:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册