2016-07-01 45 views
-1

我被分配來解決系統內存異常的問題。我是這個項目的新手,我試圖調試代碼以找到問題的確切原因。當數據從oracle數據庫打開並壓縮數據集時,會發生此問題。數據集包含超過10個表格,並且在一個表格中它包含超過100000個數據,在另一個表格中以及相同數據集中的數字相似。代碼被寫成壓縮如下,在Base64string中壓縮大型數據集

public DataSetObject(DataSet dataSet) 
     { 
      if (dataSet != null) 
      { 
       using (dataSet) 
       { 
        foreach (DataTable table in dataSet.Tables) 
        { 
         _totalRowCount += table.Rows.Count; 
        } 

        dataSet.RemotingFormat = SerializationFormat.Xml; 
        _dataSetAsString = Compressor.ConvertToString(dataSet); 
       } 
      } 
     } 

,其中壓縮機是一種實用工具CALSS,並且如下面編寫的代碼,

dsSurrogate = new DataSetSurrogate(dataSet); 
       formatter = new BinaryFormatter(); 
       formatter.TypeFormat = FormatterTypeStyle.XsdString; 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        formatter.Serialize(ms, dsSurrogate); 
        ms.Seek(0, SeekOrigin.Begin); 

        byteArray = ms.ToArray(); 
       } 

       return Convert.ToBase64String(byteArray); 

在這之後它突然拋出異常跨線程操作無效。並在日誌文件中記錄如下,

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 

Server stack trace: 
    at System.Text.StringBuilder.ToString() 
    at System.IO.BinaryReader.ReadString() 
    at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectString(BinaryHeaderEnum binaryHeaderEnum) 
    at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run() 
    at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 
    at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.UnsafeDeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallMessage) 
    at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding) 
    at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream) 
    at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg) 
+3

我建議沒有轉化爲base64字符串做的,如果你可能可以。 base64編碼將大約爲正在編碼的字節[]的長度的1/3。 – Kevin

+2

只是好奇你爲什麼需要這種格式。你的實際目標是什麼? –

+0

你的代碼中沒有實際的「壓縮」,我可以看到,或者你忘了發佈它? – Magnus

回答

1

您可以直接序列化到它可以在後臺要麼MemoryStream的或者一些臨時文件被序列化的base64流如果前者是不夠的:

  using (MemoryStream ms = new MemoryStream()) 
      // or use temporary FileStream for this if running out of memory 
      { 
       CryptoStream base64Stream = new CryptoStream(ms, new ToBase64Transform(), CryptoStreamMode.Write); 
       formatter.Serialize(base64Stream, dsSurrogate); 
       ms.Seek(0, SeekOrigin.Begin); 

       return ms.ToArray(); 
      } 
0

它似乎並沒有壓縮你的代碼中的任何東西。

無論如何,你可以做幾件事情

  1. 在您的應用程序/ Web配置添加gcAllowVeryLargeObjects
  2. 讓您的項目只在x64 CPU上運行,你可以改變,從你的項目的屬性

This是一個很好的閱讀「.NET Framework 4.5包括客戶端和服務器應用程序的新垃圾回收器增強功能」。