JIT--第一次--标记已--存根--调用--查找存根--执行机器码

C#和CIL的关系:

C#和N#都是CIL实现,但是彼此不能互通:

C#和N#公开不分满足规范,我们才能互通

CLS就是描述多语言互通的规范

内存分配:线程栈

  堆Heap:

    一个程序运行时,该进程存放引用类型变量的一块内存,全局唯一!只有一个堆

  栈Stack:

    数据结构,先进后出,线程栈,一个线程存放变量的内存(一个线程有一个)

  值类型分配在栈上,比如结构、枚举、int等

  引用类型分配在堆上,比如类、接口、委托等

引用类型

  1、调用new的时候,就会去栈上开辟内存,创建实例。这就是为什么在构造函数中跨域使用this

  2、把实例的引用传递给构造函数

  3、执行构造函数

  4、返回引用

装箱拆箱

int i=;
obect obj=i;//装箱
int k=(int)obj;//拆箱

引用类型在哪里?值类型在哪里?

  值类型的值,会随着对象的位置存储。引用类型的值,一定在堆里面。值类型的长度是确定的,引用类型的长度是不确定的,只有堆才能放各种值。

  下面有一个例子:

public class MyTest
{
private int x;
public MyTest(int n)
{
this.x=n;
}
}
MyTest t=new MyTest();//引用类型

  那么,t.x  这个3,是存放在哪里呢?是堆上还是栈上?

    ===.》出现在堆里面,因为值类型的属性,会随着对象的位置存储

 public struct ValuePoint// : System.ValueType  结构不能有父类,因为隐式继承了ValueType
{
public int x;
public ValuePoint(int x)
{
this.x = x;
this.Text = "";
} public string Text;//堆还是栈?
}

  struct是值类型,但是里面的Text,是存放在堆还是栈?答案是,对立面,因为引用类型的值,一定出现在堆里面。

string字符串内存分配

string student = "bingle1";
string student2 = student; Console.WriteLine(student);//bingle1
Console.WriteLine(student2);//bingle1 student2 = "bingle2";//=new string(APP);
Console.WriteLine(student);//bingle1
Console.WriteLine(student2);//bingle2
Console.ReadLine();
string student = "bingle1";
string student2 = "bingle2";//共享
student2 = "bingle1"; Console.WriteLine(object.ReferenceEquals(student, student2));//true

为什么是true?因为同一个变量,享元分配内存。为什么享元?节约内存。

student2 = "binglebingle";//等于重新开辟一块内存叫“binglebingle”  new String("binglebingle")
Console.WriteLine(student);//bingle1

还是bingle1,为什么?因为字符串的不可变性。为什么字符串不可以变,开辟新内存不浪费吗?因为在堆上是连续拜访的,如果有变化,会导致其他变量全部移动,成本太高,还不如重新new一个。

string student3 = string.Format("bing{0}", "le");
Console.WriteLine(object.ReferenceEquals(student, student3));//false

为什么是false?没有享元。分配地址,然后计算,才知道是"bingle"。

 string student4 = "bing" + "le";
Console.WriteLine(object.ReferenceEquals(student, student4));//true
//true 编译器优化了,直接就是bingle
string halfStudent = "le";
string student5= "bing" + halfStudent;
Console.WriteLine(object.ReferenceEquals(student, student5));
//false 也是先内存,再计算

东西放在站上速度快,但是值类型是不能继承的,长度也有限。

垃圾回收---CLR提供GC,托管堆垃圾回收

  1、什么样的对象需要垃圾回收?

    托管资源+引用类型。线程栈的是不需要垃圾回收的,用完立马就回收了。

  2、托管资源和非托管资源

    托管资源的就是CLR控制的,new的对象、string字符串。非托管就不是CLR控制的,数据库连接、文件流、句柄、打印机连接。using(SqlConnection)//被C#封装了管道了那个非托管的数据库连接资源。只要手动释放的,都是非托管的。

  3、哪些对象的内存,能被GC回收?

    对象访问不到了,那就可以被回收了。程序----入口----去找对象---建立对象图----访问不到的就是垃圾,就可以回收了。

  4、对象是如何分配在堆上的?

    连续分配在堆上的,每次分配就先检查空间够不够。

  5、什么时候执行GC?

    a、new对象的时候----临界点

    b、GC.Collection(),这个方法会强制GC

    c、程序退出时会GC

    a="123"

    a=null

    GC.Collect 可以GC,但是频繁GC是不好的,GC是全局的

    项目中有6个小时才运行new一次,什么时候GC? 不GC,可以手动GC

  6、GC的过程是怎么样的?

    N个对象,全部标机Wie垃圾,入口开始遍历,访问到的就标机可以访问(+1),遍历完就清理内存,产生不连续的内存,压缩,地址移动,修改变量指向,所以全局会阻塞。

    清理内存分两种情况:

      a、无析构函数,直接清理内存

      b、把对象转到一个单独的队列,会有一个析构函数专门做这个。通常在析构函数内部是用来做非托管资源释放,因为CLR肯定调用,所以避免使用者忘记的气矿。

  7、垃圾回收策略

    对象分代:3代

    0代:第一次分配到堆,就是0代

    1代:经历了一次GC,还存在的

    2代:经历了两次或以上的GC,还存在的。

    垃圾回收时,优先回收0代,提升小路,最多也最容器释放。0代不够,找1代,1代不够找2代,再不够就不用了。。。代的数值越大,越难回收。

    大对象堆:一是内存移动大对象;二是0代空间问题。80000字节就叫大对象,没有分代,直接都是2代。

    那么,静态资源在程序退出的时候,会GC吗?答案是,会的。(其实回收的不是变量,是某个对象所占据的内存,如果存在一个对象,指向它的引用变量的数量为0,那个GC会择机回收它占据的内存。应用程序域卸载的时候回收静态变量。)

析构函数:被动清理;Dispose:主动清理

    

 public class StandardDispose : IDisposable
{
//演示创建一个非托管资源
private string _UnmanageResource = "未被托管的资源";
//演示创建一个托管资源
private string _ManageResource = "托管的资源"; private bool _disposed = false; /// <summary>
/// 实现IDisposable中的Dispose方法
/// </summary>
public void Dispose()
{
this.Dispose(true); //必须为true
GC.SuppressFinalize(this);//通知垃圾回收机制不再调用终结器(析构器)
} /// <summary>
/// 不是必要的,提供一个Close方法仅仅是为了更符合其他语言(如C++)的规范
/// </summary>
public void Close()
{
this.Dispose();
} /// <summary>
/// 必须,以备程序员忘记了显式调用Dispose方法
/// </summary>
~StandardDispose()
{
//必须为false
this.Dispose(false);
} /// <summary>
/// 非密封类修饰用protected virtual
/// 密封类修饰用private
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (this._disposed)//已经被释放的还可以不异常
{
return;
}
if (disposing)
{
// 清理托管资源
if (this._ManageResource != null)
{
//Dispose
this._ManageResource = null;
}
}
// 清理非托管资源
if (this._UnmanageResource != null)
{
//Dispose conn.Dispose()
this._UnmanageResource = null;
}
//让类型知道自己已经被释放
this._disposed = true;
} public void PublicMethod()
{
if (this._disposed)
{
throw new ObjectDisposedException("StandardDispose", "StandardDispose is disposed");
}
//
}

CLRCore(CLR核心机制)的更多相关文章

  1. JAVA基础之两种核心机制

    突然之间需要学习Java,学校里学的东西早就忘记了,得用最短的时间把Java知识理顺,重点还是J2EE,毕竟所有的ava项目中95%都是J2EE,还是先从基础的J2SE学起吧....... 首先是了解 ...

  2. Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转

    原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...

  3. MFC六大核心机制之二:运行时类型识别(RTTI)

    上一节讲的是MFC六大核心机制之一:MFC程序的初始化,本节继续讲解MFC六大核心机制之二:运行时类型识别(RTTI). typeid运算子 运行时类型识别(RTTI)即是程序执行过程中知道某个对象属 ...

  4. MFC六大核心机制之一:MFC程序的初始化

    很多做软件开发的人都有一种对事情刨根问底的精神,例如我们一直在用的MFC,很方便,不用学太多原理性的知识就可以做出各种窗口程序,但喜欢钻研的朋友肯定想知道,到底微软帮我们做了些什么,让我们在它的框架下 ...

  5. 第七章 探秘Qt的核心机制-信号与槽

    第七章 探秘Qt的核心机制-信号与槽 注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用 ...

  6. WTL的核心机制

    WTL背景介绍 WTL是微软ATL开发组成员Nenad Stefanovic先生在ATL Windowing机制上发展起来的一整套GUI框架,运用template技术组织和创建GUI对象,构筑了精致的 ...

  7. java核心机制

    Java中有两种核心机制:Java虚拟机(Java Virtual Machine).垃圾收集机制(Garbage collection) 一.核心机制之Java虚拟机 ① Java虚拟机可以理解成一 ...

  8. Qt核心机制与原理

    转:  https://blog.csdn.net/light_in_dark/article/details/64125085 ★了解Qt和C++的关系 ★掌握Qt的信号/槽机制的原理和使用方法 ★ ...

  9. 前端工程化系列[06]-Yeoman脚手架核心机制

    在前端工程化系列[05] Yeoman脚手架使用入门这边文章中,对Yeoman的使用做了简单的入门介绍,这篇文章我们将接着探讨Yeoman这个脚手架工具内部的核心机制,主要包括以下内容 ❏ Yeoma ...

随机推荐

  1. C语言程序设计100例之(24):数制转换

    例24   数制转换 题目描述 请你编一程序实现两种不同进制之间的数据转换. 输入格式 共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用 ...

  2. springaop\ cglib\ AspectJ

    元编程 vs 动态代理 vs isa代理 springaop的底层实现有两种,一种是jdk的动态代理,另一种是cglib,springaop没有用到aspectj,只是借鉴了它并添加了aspectj风 ...

  3. RabbitMQ与Spring的框架整合之Spring Cloud Stream实战

    1.RabbitMQ与Spring Cloud Stream整合实战.SpringCloud Stream整体结构核心概念图,如下所示: 图示解释:Outputs输出,即消息的发送端.Inputs输入 ...

  4. C#斐波那契数列求法(比较阶乘和循环所用时间)

    using System; namespace ConsoleApp3 { class Program { static void Main(string[] args) { Console.Writ ...

  5. python爬虫网页解析之parsel模块

    08.06自我总结 python爬虫网页解析之parsel模块 一.parsel模块安装 官网链接https://pypi.org/project/parsel/1.0.2/ pip install ...

  6. 剑指offer 24:二叉搜索树的后序遍历序列

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 解题思路 后序遍历,顾名思义根节点位于尾部,故可将 ...

  7. none 和 host 网络的适用场景

    我们会首先学习 Docker 提供的几种原生网络,以及如何创建自定义网络.然后探讨容器之间如何通信,以及容器与外界如何交互. Docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 h ...

  8. Django-xadmin后台配置富文本编辑器(方法一)

    1.https://github.com/twz915/DjangoUeditor3下载包,进入包文件夹,找到DjangoUeditor包拷贝到项目下,和xadmin同级目录 2.找到项目的setti ...

  9. 第6次作业--static关键字、对象

    题目1:编写一个类Computer,类中含有一个求n的阶乘的方法.将该类打包,并在另一包中的Java文件App.java中引入包,在主类中定义Computer类的对象,调用求n的阶乘的方法(n值由参数 ...

  10. 运用tensorflow写的第一个神经网络

    因为实训课要用LSTM+attention机制在钢材领域做一个关系抽取.作为仅仅只学过一点深度学习网络的小白在b站上学习了RNN,LSTM的一些理论知识. 但只懂得一些理论知识是无法完成关系抽取的任务 ...