zx40509985  

   很久没写C 和C++等底层了。但是今天看了一个帖子,再看了很多回复 所以就想写一下这篇文章。只是说一下思想,代码中也许会有伪代码,请各位自行分析。

   <法师10G来个传送门>

   好吧,我从内存角度先说一下。

   首先要明白,我们的内存,从物理上来讲都是完全一样的,不分堆(Heap)和栈(stack),但是操作系统IO会把其分为不同用途的区域或者段,叫做节 (section).一般的程序后有静态存储区,堆栈区,代码区等。而堆是在程序运行时向操作系统申请的。(注意:有些内存地址会被系统作为保留地址 永远不可以被分配)
   早期的程序员,内存必须自己管理,栈的地址是一个挨一个向下逐级分配(数组是最好的代表)。而堆是一个无序内存,他是IO随即分配的一块地址。既然是无序地址,那要如何操纵他呢?这就是讲到了 指针(ptr),他是利用指针记录的地址去操作堆中的那块内存.

   比如 我们ClassA * a = new ClassA;  这里(ClassA * a)实际上是在栈上分配了一块内存指针地址,而( new ClassA) 这里是在堆上分配了一块内存去实例化ClassA这个对象(构造函数,字段,虚方法指针等等),这里的a地址刚好对应的就是new ClassA这块刚分配的内存地址.(**大学跟我一起逃课打传奇和魔兽世界的听不懂不要紧,只是说个思想).
   但是当他用完这块堆内存后,系统不会为他回收,所以他必须free或者delete这块内存。现在的高级语言程序员为什么会对malloc这样的内存分配和free,delete这样的内存删除会这么迷茫呢。

   原因就在这里了,C#有一个垃圾回收装置,叫GC(garbage collection),当他发现堆上的这块内存,已经超出他的生命周期{},或者已经没有指针指向他的时候,他会自动回收这块内存,当然这也是C#效率较低的一个重大原因,但是,他不是实时的,还是那句话,要考虑效率问题,他有点类似文件搜索和扫描的意思。这样来说他的堆已经不是普通的堆,而是叫托管堆(manage heap)

   讲的晕了,来个例子吧。

   ClassA a = new ClassA("aa");  //分配来讲,差不多,具体区别自己去查。

   注意了。

   a = new ClassA("bb"); //这个时候,指针还在但是指向发生了变化,a对象指向了一个新的对象?那以前的new ClassA("aa") 怎么办?如果这要是一个C++的程序,那OK了,您老已经内存泄露了。但是C#里有GC,当他发现这块内存已经无效的时候,他会自动释放这块内存。呵呵 是不是很有意思。

   所以说

  SimpleClass s = new SimpleClass("method1");
            s
= null;
   这个s=null; 当他指向null的时候,GC会把他原来指向的 new SimpleClass("method1"); 去回收。因为null表示一个空地址或者首地址,是一个无效的值。微软是不推荐这样写的。因为思想上的问题,导致代码紊乱。所以当你想回收的时候,让他=null。再回收,是一个很没有必要的事。(说难听点就是脱了裤子放P)

   而静态的字段,static.我刚也说了,从逻辑上来讲,他并不存储在堆或者栈上,他存储在IO分配的静态储存区。既然是静态的,那肯定就是要优先于构造函数去生成,为的就是做这个事,指向不指向NULL,也无所谓了。一般不要搞静态,既然要搞就继续搞下去吧。万一RAID共同维护你这个static 的NULL对象。实在是个很麻烦的事。

   本人凭经验所写的随笔,能力有限,只是希望对大家能够有一些启发,不要光知道某一个方法怎么用。只有知道方法底层是如何实现的,才能更好的帮助你去学习和进步,有错误的地方欢迎各位高手指出,谢谢。

 

 

 

 


 

 

posted on 2011-04-07 13:56  无拘无束  阅读(1840)  评论(19编辑  收藏  举报