2014-09-17 14 views
0

В моем приложении vb, где я загружаю файлы на сайт FTp, я использую массив большого размера. При объявлении массива иногда я получаю ошибку как Exception of type 'System.OutOfMemoryException' was thrown.System.OutOfMemoryException при распределении массива большого размера

я объявил массив в качестве

Const BufferSize As Integer = 400000000 
Dim content(BufferSize - 1) As Byte 

На самом деле 400000000 выйдет около 380 МБ. У меня есть 4 ГБ ОЗУ, а использование невелика. Почему эта ошибка иногда появляется? Как это можно решить?

+0

Сколько памяти выделяется для вашего приложения? Это важно, а не общая системная память. – jmcilhinney

+0

@jmcilhinney Вы имеете в виду, сколько памяти используется для приложения (от taskmanager)? –

ответ

0

Отказ от моих ранних same question и answer (с благодарностью Aik за отличное объяснение).

Даже если у вас есть 4gb бара, нет никакого способа узнать, что у вас есть 380 мб свободного пространства. Если фрагментация вашей ОЗУ слишком велика, это может привести к проблемам.

Вы должны бросить свои данные, чтобы преодолеть эту проблему (см это answer ...)

Объяснение по AIK:

Для примера на моей машине я не могу выделить больше, чем 908 000 000 байт в одном массиве, но я могу выделить 100 * 90 800 000 без каких-либо проблем, если она хранится в более массивах:

Dim toBigArray As Byte() = New Byte(908000000) {} 
'doesn't work (6 zeroes after 908) 
' allocation in more arrays 
Dim a As Byte()() = New Byte(100)() {} 

For i As Integer = 0 To a.Length - 1 
    ' it works even there is 10x more memory needed than before 
     ' (5 zeroes after 908) 
    a(0) = New Byte(90800000) {} 
Next 
+0

Если я сделаю так, как сказал в ответе, то как я могу использовать этот размерный массив в Filestrem. читать функцию. Он принимает одноразмерный массив. –

+0

То, что я пытался сделать, это то, что вы можете выделить слишком много памяти в один массив. Вы попадете в неприятности (например, посмотрите на свой вопрос). Вы должны его обмануть (как в примере кода ниже). Вы можете вручную настроить буферизацию для оптимальной скорости. – User999999

0

Использование таких больших массивов - плохая идея. Вы можете передать файл небольшими кусками. Вот некоторые примеры кода из этого link

''' <summary> 
''' Methods to upload file to FTP Server 
''' </summary> 
''' <param name="_FileName">local source file name</param> 
''' <param name="_UploadPath">Upload FTP path including Host name</param> 
''' <param name="_FTPUser">FTP login username</param> 
''' <param name="_FTPPass">FTP login password</param> 

Public Sub UploadFile(ByVal _FileName As String, ByVal _UploadPath As String, ByVal _FTPUser As String, ByVal _FTPPass As String) 
Dim _FileInfo As New System.IO.FileInfo(_FileName) 

' Create FtpWebRequest object from the Uri provided 
Dim _FtpWebRequest As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(New Uri(_UploadPath)), System.Net.FtpWebRequest) 

' Provide the WebPermission Credintials 
_FtpWebRequest.Credentials = New System.Net.NetworkCredential(_FTPUser, _FTPPass) 

' By default KeepAlive is true, where the control connection is not closed 
' after a command is executed. 
_FtpWebRequest.KeepAlive = False 

' set timeout for 20 seconds 
_FtpWebRequest.Timeout = 20000 

' Specify the command to be executed. 
_FtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile 

' Specify the data transfer type. 
_FtpWebRequest.UseBinary = True 

' Notify the server about the size of the uploaded file 
_FtpWebRequest.ContentLength = _FileInfo.Length 

' The buffer size is set to 2kb 
Dim buffLength As Integer = 2048 
Dim buff(buffLength - 1) As Byte 

' Opens a file stream (System.IO.FileStream) to read the file to be uploaded 
Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead() 

Try 
' Stream to which the file to be upload is written 
Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream() 

' Read from the file stream 2kb at a time 
Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength) 

' Till Stream content ends 
Do While contentLen <> 0 
' Write Content from the file stream to the FTP Upload Stream 
_Stream.Write(buff, 0, contentLen) 
contentLen = _FileStream.Read(buff, 0, buffLength) 
Loop 

' Close the file stream and the Request Stream 
_Stream.Close() 
_Stream.Dispose() 
_FileStream.Close() 
_FileStream.Dispose() 
Catch ex As Exception 
MessageBox.Show(ex.Message, "Upload Error", MessageBoxButtons.OK, MessageBoxIcon.Error) 
End Try 
End Sub 


HOW TO USE: 

' Upload file using FTP 
    UploadFile("c:\UploadFile.doc", "ftp://FTPHostName/UploadPath/UploadFile.doc", "UserName", "Password") 

EDIT 1:

Попробуйте эти ссылки могут быть это может помочь вам.

1) My.Computer.Network.UploadFile

2) Improve Performance of FtpWebRequest

+0

Прежде чем использовать 2048 как buffLength. Но загрузка будет медленной. Я тоже ее протестировал. 100 МБ-файл занимает 18 минут, чтобы загрузить, если я установил 2048 как buffLength, и требуется всего 3 минуты, если длина буфера равна 400000000 с той же скоростью интернета –

Смежные вопросы