日期:2014-05-18  浏览次数:22036 次

关于释放byte[]内存
有人说过,值类型存在堆栈上,不用的时侯就自动释放。
可我今天遇到这种情况很奇怪,byte[]执行GC.Collect();才能释放内存,否则一直占用内存。
先说一下我主要的目的:将本地本文件用webservice方式上传至服务器

代码如下:
C# code

 public byte[] ReadBytes(string path)
        {
            FileStream fs = null;//= new FileStream(path, FileMode.Open, FileAccess.Read);
            byte[] data=null;
            BinaryReader r = null;// new BinaryReader(fs);
            try
            {
                using (fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    using (r = new BinaryReader(fs))
                    {
                        data = r.ReadBytes((int)fs.Length);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (fs!=null)
                {
                    fs.Close();
                    fs.Dispose();
                }
                if (r != null)
                {
                    r.Close();
                }
              
            }
            return data;
        }
        public bool PutFile(byte[] buffer, string filepath)
        {
            bool isSuc = false;

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            BinaryWriter binWriter =null;
            try
            {
                using (binWriter = new BinaryWriter(File.Open(filepath, FileMode.CreateNew, FileAccess.ReadWrite)))
                {
                    binWriter.Write(buffer);
                    binWriter.Flush();
                }
                isSuc = true;
            }
            catch (Exception ex)
            {
                isSuc = false;
                throw ex;
            }

            finally
            {
                if (binWriter!=null)
                {
                    binWriter.Close();
                }
                GC.Collect();
                //GC.Collect(3, GCCollectionMode.Optimized);
            }

            //有此句GC不会回收,无此句GC会回收
            //int length = buffer.Length;
            return isSuc;
        }



调用代码:
  string path = @"D:\软件\SQL2005Express\SQLEXPR_TOOLKIT_CHS.EXE";
  byte[] bFile = ReadBytes(path);
  MessageBox.Show(PutFile(bFile, @"E:\SQLEXPR_TOOLKIT_CHS.exe").ToString());


------解决方案--------------------
“否则一直占用内存”?你怎么知道的?
------解决方案--------------------
程序关闭时会自动释放内存吗
------解决方案--------------------
问题关键是byte是值类型,但byte[]是引用类型,byte和byte[]是两个不同的类型,

所有数组都是引用类型,实际上数组是Array类的实例,数组作为Array类的实例也是有自己的方法的,

既然byte[]是Array类的实例,它自然是在heap中分配,并且必须使用GC.Collect才能释放,byte[]并不是分配在stack中,

------解决方案--------------------
byte[]是引用类型,分配在托管堆上而不是堆栈上。
------解决方案--------------------
没必要写 GC.Collect(); 这句

另外 byte是值 byte[]也是值 只是前者的值就是一个字节(一个数) 分配在栈上 比如234 代表234这个数。 
后者的值代表一个地址 也是分配在栈上(只是它的地址是指堆上的地址) 比如12345 代表堆上12345这个地址

两者都是值 都是一个数

前者占一个byte 由栈自动释放
后者在32位机器上 占4byte 也是由栈自动释放 它所指的空间由.Net自动释放 

这个C++中更好理解
------解决方案--------------------
应该是.NET的垃圾回收还没执行吧。GC.Collect(); 是强制释放。
------解决方案--------------------
探讨

呵呵,不写GC.Collect();内存会在执行其它操作或下一次操作时自动释放
如果你执行完这个操作什么事都不做,他就不释放,很奇怪。。。

------解决方案--------------------