2013-05-02 79 views
0

我使用TCP套接字将每个文件从pc发送到手机,每个文件大约10 Mbs。 在手机端我收到的数据是这样的:套接字数据传输 - 内存不足异常

Dim B As Byte() = New Byte(Socket.ReceiveBufferSize - 1) {} 
    Me.Args.SetBuffer(B, 0, Socket.ReceiveBufferSize) 
    Me.Socket.ReceiveAsync(Me.Args) 

ReceiveBufferSize属性设置为30000000 这是我读的方式:

Dim R As Byte() = New Byte(Me.Args.BytesTransferred - 1) {} 
Dim s As New MemoryStream(Me.Args.Buffer) 
Me.Args.SetBuffer(0, 0) 

s.Read(R, 0, ntpData.Length) 
s.Dispose() 

这个过程需要一个巨大的内存容量(约300Mbs),因此我无法在低价设备上运行该应用程序,该设备的内存使用限制为180Mbs。 每当手机接收到某个东西时,我都不能.Dispose(),因为它会抛出一个OjbectDisposed异常。 如何释放内存?

回答

1

这听起来像问题可能会被扭转。你怎么能使用少内存?例如,您可以:

  • 从套接字以较小的块下载数据并重新使用相同的缓冲区而不是重新分配它。
  • 将数据写入隔离存储流而不是内存,并且只在给定时间点才将应用程序中显示的内容加载到memroy中。

(这将取决于你工作的具体情况)

你也应该确保你已经分配的内存是,一旦你用它做垃圾收集,通过确保没有是持有一个对它的引用

另外,你有没有分析应用程序来确认它确实是这个套接字内存导致的问题,还是实际上是由于其他地方的其他内存?

+0

我在应用程序中“评论了其他程序”,是的,我很确定这是问题所在。不过,我会尝试第一个解决方案,如果还不够,我还会去第二个解决方案。谢谢 – fillobotto 2013-05-02 10:26:49

+0

在用户界面中显示大量图像是高内存使用率的常见原因,因此请留意。 – 2013-05-02 10:36:44

+0

当然,但我没有显示任何图像。问题是ReceiveBufferSize太大,但无法弄清楚如何在块中执行ReceiveAsync。 – fillobotto 2013-05-02 10:59:39

0

你很幸运,因为你在发展阶段失去了记忆。

永远不要使用windows Phone上大于84KB的缓冲区(字节数组)大小,GC不会收集大于84KB的字节数组中的数据。

你的代码应类似于:

Try 
      stream.Position = 0 
      Dim totalRead As Long = 0 
      Dim readBuffer As Integer 
      Dim bufferSize As Long = 4096 'under 86KB 
      Dim readArray = New Byte(bufferSize - 1) {} 
      While totalRead < stream.Length 
       readBuffer = Await stream.ReadAsync(readArray, 0, bufferSize) 
       totalRead += readBuffer 
       'Use readArray here 
      End While 
      stream.Dispose() 
     Catch ex As Exception 
      'Log My exception 
     Finally 
      stream.Dispose() 
     End Try 

只是试图改变类似这样的代码,你会不会超过50MB RAM

好运。

+0

这对我的情况没有帮助,事实上,在处理它之前我不知道流的长度。我所能做的就是设置一个缓冲区,在该缓冲区中,将按照上面的代码所示的方式放置流。 – fillobotto 2013-05-03 13:32:52

0

因为我找不到任何真正的解决方案来解决我的问题,所以我设法使用了解决方法。

每个数据包都标有标题。 在发送大量数据之前,我向客户端发送具有不同头的数据包。然后客户端识别这种头部并读取头部旁边的字节:它们包含即将到来的流的长度。所以客户端设置缓冲区的长度并等待数据来。