读书人

关于释放byte[]内存解决方案

发布时间: 2012-05-12 15:39:31 作者: rapoo

关于释放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();内存会在执行其它操作或下一次操作时自动释放
如果你执行完这个操作什么事都不做,他就不释放,很奇怪。。。

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


有时间及兴趣的话,可以读下msdn。

http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

我也没读过,太长了。
[解决办法]
如果不写GC.Collect();内存会自动释放,但不是在下一次操作时释放,而是在系统认为需要的时候自动释放,自动释放的时机是.Net的策略决定的,你很难预测到系统什么时候释放内存,所以你会看到一段时间内这个内存没有释放,不过过了半个小时后也许就会释放了,

探讨

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

[解决办法]
。只是楼主的错误感官吧。是会自动释放的。你那样看的是不准确的、
[解决办法]
这个纯粹是代码逻辑问题:
当你使用int length = buffer.Length;这句的时候
方法还没有返回,当然不会GC在上面调用的时候,发现buffer的生命周期还在,处于需要使用的状态,当然内存也会保留,直到方法return返回到调用处的时候,这个时候buffer的内存就会自动释放了。
另外,array是引用类型的,如果在调用方仍然有使用buffer的话,那么buffer的生命周期还没有失效,还是不会回收
普通对象内存会不会被自动回收,是看变量的生命周期。当变量的生命周期死了以后,就会被回收了。
另外像Stream等特殊的对象会占用系统资源的,需要手动调用其析构函数dispose或者close
[解决办法]
byte[]是引用~所以数组都是
GC收集不可控 判断是否可以收集是个有向图的问题 看你的这个对象是否还有引用指向他

读书人网 >C#

热点推荐