关于释放byte[]内存有人说过,值类型存在堆栈上,不用的时侯就自动释放。可我今天遇到这种情况很奇怪,byte[]
关于释放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(); 是强制释放。
[解决办法]------解决方案--------------------
有时间及兴趣的话,可以读下msdn。
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx
我也没读过,太长了。
[解决办法]如果不写GC.Collect();内存会自动释放,但不是在下一次操作时释放,而是在系统认为需要的时候自动释放,自动释放的时机是.Net的策略决定的,你很难预测到系统什么时候释放内存,所以你会看到一段时间内这个内存没有释放,不过过了半个小时后也许就会释放了,
[解决办法]。只是楼主的错误感官吧。是会自动释放的。你那样看的是不准确的、
[解决办法]这个纯粹是代码逻辑问题:
当你使用int length = buffer.Length;这句的时候
方法还没有返回,当然不会GC在上面调用的时候,发现buffer的生命周期还在,处于需要使用的状态,当然内存也会保留,直到方法return返回到调用处的时候,这个时候buffer的内存就会自动释放了。
另外,array是引用类型的,如果在调用方仍然有使用buffer的话,那么buffer的生命周期还没有失效,还是不会回收
普通对象内存会不会被自动回收,是看变量的生命周期。当变量的生命周期死了以后,就会被回收了。
另外像Stream等特殊的对象会占用系统资源的,需要手动调用其析构函数dispose或者close
[解决办法]byte[]是引用~所以数组都是
GC收集不可控 判断是否可以收集是个有向图的问题 看你的这个对象是否还有引用指向他