<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一種MemoryStream的替代方案

      簡介

      這篇文章闡述了當使用MemoryStream處理大型數據集時經常觸發的模棱兩可的OutofMemoryException異常,并且介紹了一個類——MemoryTributary,他可以用來替代.NET內置的MemoryStream,并且能夠支持大型數據的處理。

      背景

      當試圖使用MemoryStream處理較大數據(in the order of tens of MB)時,它通常會引發OutofMemoryException異常。這是不是因為,正如其命名的那樣,超出了系統內存的限制了呢?但實際上那都是進程的虛擬地址空間。

      當進程從Windows申請內存的時候,內存管理器并沒有從RAM中分配地址空間,但是“頁面”——存儲塊(通常是4KB)可以存在于RAM、磁盤或者任何內存管理器能夠決定存儲它們的地方。頁面映射到進程的地址空間,因此,假如當進程試圖從[0xAF758000]開始訪問內存時,它實際上是在訪問[第496頁]開始的地方,無論是否恰好是[第496頁]。可以為進程分配任何大小的足夠的內存,只要磁盤空間充足,并可以將其中的一大部分作為虛擬地址空間,這適用于任何時候。在這個分配過程中會產生大量的小碎片(這里是指存儲塊)。

      這是因為進程地址空間是支離破碎的:大部分都被操作系統占用,諸如應用程序映像、庫以及其他預分配的空間等。一旦內存管理器分配了所請求的相當于頁面大小的內存,就必須在進程內映射到(虛擬)地址空間。而當剩余的地址空間中沒有足夠的連續空間時,頁面就無法被映射,從而導致內存分配失敗,也就引發了OutofMemoryException異常。

      這個過程并沒有耗盡空間和地址,它運行在連續的地址上。要看到這個(如果你在用64位系統),在x86目標平臺下編譯如下程序并運行它,然后再編譯為x64目標平臺,看看兩者的區別。

       1 static void Main(string[] args)
      2 {
      3 List<byte[]> allocations = new List<byte[]>();
      4
      5 for (int i = 0; true; i++)
      6 {
      7 try
      8 {
      9 allocations.Add(new byte[i * i * 10]);
      10 }
      11 catch (OutOfMemoryException e)
      12 {
      13 Console.Write(string.Format("Performed {0} allocations",i));
      14 }
      15 }
      16 }

      .NET當前實現的MemoryStream使用了一個字節數組作為后備存儲。當要寫入的內容超出數組長度的時候,容量就會自動擴展一倍(老陳注:這是.NET數組自身的內存分配機制)。根據程序這種行為,基于這種后備存儲機制的MemoryStream會很快就需要比可用虛擬地址空間更多的內存。

      代碼用例

      這個解決方案并不是申請更多更大的連續內存去存儲流中包含的數據。MemoryTributary內部使用了4KB的動態集合來作為后備存儲,實現按需分配。

      MemoryTributary從Stream派生,因此可以像使用其他Stream一樣的使用它,類似于MemoryStream。

      MemoryTributary不過是想作為MemoryStream的一個替代方案,但不是可以在任何情況下都可以替代MemoryStream的,以下是一些注意事項:

      1. MemoryTributary沒有完全實現MemoryStream所有的構造函數(因為MemoryTributary的容量是沒有人為限制的)。MemoryTributary的初始容量從一個byte[]開始。
      2. MemoryTributary是Stream的子類,而不是MemoryStream,所以不能用在僅接受MemoryStream成員的地方。
      3. MemoryTriburary沒有后備存儲實現GetBuffer(),類似功能的方法是ToArray(),但是要慎用!

      使用MemoryTributary要注意以下幾點:

      1. 塊是在訪問時按需分配的(例如在讀取或寫入時)。在讀取之前,重新檢查Position,以確保讀取操作是在流范圍內進行的。
         1 // 創建 MemoryTributary 的新實例:此時Length為0,Position為0,沒有內存被分配
        2 MemoryTributary d = new MemoryTributary();
        3
        4 // 因為Length為0所以返回-1,沒有內存被分配
        5 int a = d.ReadByte();
        6
        7 // Length現在設定為10000字節,但是沒有內存被分配!
        8 d.SetLength(10000);
        9
        10 // 現在有3個內存塊被分配了,
        11 // 但是b是未定義的,因為它們還沒有完成初始化
        12 int b = d.ReadByte();
      2. 內存是分配在連續的塊上的,也就是說,如果第一個塊是塊3的話,那么塊1和塊2也會被自動分配掉;
      3. MemoryTributary包含了一個ToArray()方法,但這是不安全的;
      4. 作為替代,MemoryTributary使用ReadFrom()和WriteTo()這兩個方法對大數據進行操作。

      性能指標

      在容量和速度上,MemoryStream和MemoryTributary都是很難預料的,因為這依賴于很多因素。一個很重要的因素是當前進程的內存碎片——一個進程分配了大量內存將會導致大量內存碎片的發生。

      容量

      平均崩潰臨界值(MB)
      MemoryStream 488
      MemoryTributary 1272

      速度(訪問時間)

      流測試執行時間比對 (ms)

      讀寫容量
      (MB)

      MemoryStream MemoryTributary
      (4KB Block)
      MemoryTributary
      (64KB Block)
      MemoryTributary
      (1MB Block)
      10 10 13 11 7
        3 5 3 3
        3 6 3 3
        3 5 3 3
        4 5 3 3
        3 6 3 3
      100 100 148 123 52
        34 54 42 35
        34 48 35 34
        35 47 36 35
        34 48 36 35
        35 51 35 35
      500 516 390 290 237
        167 222 184 170
        168 186 154 167
        167 187 151 168
        167 186 151 168
        167 185 153 168
      1,000 1185 1585 1299 485
        347 547 431 344
        343 463 350 345
        338 462 350 345
        3377 461 349 345
        339 465 351 343

      代碼下載

      請到原文地址下載:http://www.codeproject.com/Articles/348590/A-replacement-for-MemoryStream

       

      posted @ 2012-03-25 10:12  O.C  閱讀(9492)  評論(9)    收藏  舉報
      主站蜘蛛池模板: 亚洲av产在线精品亚洲第一站| 亚洲高清国产自产拍av| 国产影片AV级毛片特别刺激| 黑人巨茎大战欧美白妇| 99精品视频九九精品视频| 欧美人成精品网站播放| 无码精品国产va在线观看dvd| 18av千部影片| 精品国产一区二区三区蜜臀| 精品国产午夜福利在线观看| WWW丫丫国产成人精品| 免费A级毛片樱桃视频| 四虎www永久在线精品| 成人亚洲精品一区二区三区| 亚洲中文字幕五月五月婷| 中国少妇人妻xxxxx| 92自拍视频爽啪在线观看| 中文字幕日韩有码国产| 熟女视频一区二区在线观看| 国产精品一码在线播放| 国产99在线 | 亚洲| 成人性能视频在线| 疯狂添女人下部视频免费| 成人免费A级毛片无码片2022| 若羌县| 久久精品国产精品亚洲综合| 国产午夜福利精品视频| 乌兰县| 亚洲国产美女精品久久久| 国产99久久精品一区二区 | 亚洲精品一区二区天堂| 浙江省| 国产精品久久久久影院色| 亚洲av在线观看| 在线涩涩免费观看国产精品| 亚洲人成线无码7777| 国产av永久无码天堂影院 | 国产高清在线a视频大全| 国产精品麻豆va在线播放| 亚洲熟妇精品一区二区| 久久99精品国产自在现线小黄鸭|