转自:kiba518cnblogs.com/kiba/p/10971744.html 前言 在职场中,确立自身的技术水平很重要,因为,如果你被标记成了技术菜鸟,那么你的工作一旦做快了,大家就会一致的认为这个任务比较简单;如果你未如期完成,则会被各种明嘲暗讽,你不但无法获得合理的表扬,还会无端被迫接受攻击。 但是,如果你被标记成了技术高手,那么你就算任务延期也会被理解,因为,他们会认为你当前的任务太难了。而且,即便你有些性格缺陷,大家也是会接受你,他们会认为这是你的特点。 所以,进入新的工作岗位,第一件事是确立自身的技术水平,这会让你省却很多不必要的麻烦,会让你在公司工作时,保持比较良好的状态,进而延长你在公司任职的时间。 那么这些与内存有什么关系呢?因为就是会有些人,会以你不了解【他们的】内存来攻击你的技术水平。 因为在职场生存,除了不停的提升自己以外,还是要关注周围同事对你的看法,如果有人以一些你不了解的技术问题来否定你的技术水平,这就会很影响你在其他同事心中的形象,从而影响你在职场中建立的技术水平的等级,这会让你在未来的职场生涯中遇到更多的麻烦。 虽然,害人之心不可有,但是防人之心不可无,所以,我们需要了解【他们的】内存,来保护自己,在被攻击时,做更好的应对,甚至反击。 托管内存与非托管内存 托管内存 C#语言开发的程序所使用的内存,我们称之为托管内存。那么什么是托管内存呢?我们可以先理解为,C#专用内存;即当C#的程序运行起来,会向电脑内存申请一块专用的内存区,而这块内存区,就叫做托管内存。 在C#语言开发的程序中,我们所声明的变量,不论是常量,还变量,都在这块内存中。即,我们声明一个int k或是声明一个对象 new Class,他们都是在这块内存中的。 而这块内存(托管内存),它很特别,它自身是带管理功能的,即,它自己会判断,你声明的内存还用不用,不用他就给回收了。 既然是管理,那就肯定有个管理工具,那么,托管内存的管理工具是什么呢? GC——控制系统垃圾回收器,这个就是托管内存的管理工具了,他是专门管理内存回收的,这里就不过多的讲解GC了,有兴趣的朋友可以参考下面的网址。 参考网址: GC——控制系统垃圾回收器 https://docs.microsoft.com/zh-cn/dotnet/api/system.gc?redirectedfrom=MSDN&view=netframework-4.8 弱引用 WeakReference https://docs.microsoft.com/en-us/dotnet/api/system.weakreference?redirectedfrom=MSDN&view=netframework-4.7.2 非托管内存 既然,C#语言开发的程序所使用的内存,都叫托管内存,那么非托管内存自然就是C#程序不使用的内存了。 那么,C#程序不使用的内存,有什么用呢?我们为什么要学习呢? 因为,很多语言并不像C#这么优秀,有专门的内存管理机制,比如C++;所以,他们的变量和常量都是存储在非托管内存区的(对于很多语言而言,并没有托管内存和非托管内存之分,他们就一个内存,在内存中找个地址,然后存储数据)。 所以,当我们在做项目遇到要和其他语言进行交互时,就要接触非托管内存了,因为很多时候,我们需要从非托管内存中获取一些的变量,或者向非托管内存中写入一些数据供其他语言调用。 因此,从理论上来讲,C#语言对内存的管理是最复杂的,远大于C++,因为它不仅自己开辟了一块内存专区,同时又兼顾着控制专区外的内存。 下图为托管内存与非托管内存的关系。 ![]() 安全代码与非安全代码 安全代码 C#的安全代码就是C#日常写的代码,其特点就是代码中声明的变量都在托管内存;而之所以叫安全代码,则是因为内存全部托管给了内存管理器,不存在内存泄漏的问题(当然,这是理论上,实际情况某些微软的控件还是存在内存泄漏的问题,相信一定有人遇到过,不过99%的情况下是没问题的)。 非安全代码 非安全代码显然是与安全代码相对的,即非安全代码的变量所使用的内存都在非托管内存区。 因为常规状态下我们写的代码都是安全代码,所以想写非安全代码一定要加个特殊标记,那就是unsafe。 unsafe { } 如上述代码,在unsafe的区域内,我们就可以编写非安全代码。 但C#项目在默认的情况下是不支持非安全代码的,即当我们尝试些unsafe时,编译器会报错。为什么不默认不允许我们使用非安全代码呢?很简单因为它不安全嘛。 想启用C#的非安全代码设置也很简单,右键项目—属性—生成,如下图所示: ![]() 默认情况下,【允许不安全代码】是非勾选状态;当我们勾选上之后,编译器就允许我们使用unsafe了。 那么,在unsafe区间如何控制非托管区域的内存呢? 这就需要使用到指针了,下面我们讲一下C#中的指针。 注意:非安全代码并不是C#的主要功能,而是为了兼容其他使用非托管内存的语言而存在的,所以即便你不了解也并不会影响你的技术水平,但在职场中,这块的内容非常容易成为菜鸟攻击你的利器,所以学会它是职场生存的重要手段之一。 指针(Pointer)与句柄(IntPtr) 作为C#开发,我们要知道【宏】和【指针】 |