[問題] 程式使用記憶體的上限

作者: googled (15357)   2014-05-21 02:19:26
各位好,小弟用Qt Creator寫了一個瀏覽照片的程式
程式中會大量的開啟指定的圖檔然後顯示到視窗中
但每次讀取到一定的量後,程式就會沒辦法再讀取圖片
嚴重甚至崩潰,檢查後才發現似乎跟程式使用的記憶體有關
每當我程式讀取的圖片佔用的記憶體到了1.2G以上,
程式很容易就無法再讀取圖片了,
我很確定我電腦的記憶體還有很多尚未使用的部分@@
我電腦有16G的記憶體,作業系統是WIN7 64位元
我用工作管理員看效能那一欄下面的實體記憶體部分有四個內容
分別是『總共、快取的、可用、未使用』
根據我GOOGLE查到的結果,『未使用』其實只是還沒被作業系統移到『快取的』而已
電腦閒置的時間越久,未使用就會越少,快取的就會越多,
這樣電腦中的程式要用到記憶體時就可以迅速的從『快取的』取出來使用,
我打開電腦的VM ware時,『快取的』的確會大量的減少
但我發現我程式每次在讀取圖片時,『快取的』都不會減少,
反而減少的都是『未使用』
當下一張讀取的圖片檔案大小超過『未使用』時,程式就沒辦法讀取照片了@@
而剛好我電腦的『未使用』每次都差不多是剩1.1G左右
我不知道這段敘述跟我遇到的問題有沒有相關ˇ_ˇ
我也不敢100%確定我這段敘述真的是正確的
所以想請問該怎麼樣才可以讓程式讀取更多的照片?
或者是說使用更多的記憶體
這問題我真的查了很久都查不太到解答...
本來有查到說有人講我應該要用64位元的編譯器才行,
但我在想這樣32位元的系統不就不能執行了嗎?
而且有很多32位元的程式都會超過2G以上的不是嗎@@
不曉得有沒有高手可以指點一下的,拜託了
我寫了一個測試的讀檔程式放上來,不知道這樣有沒有違規,
有的話麻煩告知,我會速刪的。
這程式會讀取同資料夾下11.7MB的1.jpg圖檔,按一次按鈕會讀取五次
因為沒有寫執行緒,所以讀取過程會delay一段時間,
想說可以測試看看是不是真的『未使用』的部分不夠大時程式就無法讀取了。
https://mega.co.nz/#!UBsnCBSZ!hsvJ1ru5uU8KhL8zGoqsYww_3cINiUjK4Q3AAUzYQj0
不過寫了這程式反而讓我發現其他事情,
明明照片才11.7MB,可是開啟一次卻會讓程式佔用大約370M的記憶體
所以我自己的電腦只能開到三張,就沒辦法再開了
照片的大小是16744*5615,我把他相乘後再*4就是376M,
難道程式讀取照片佔用的記憶體是看這個@@?
我一直以為是看檔案大小,雖然發現這事情,不過問題還是存在ˇ_ˇ
拜託各位指點一下了,謝謝
作者: LPH66 (-6.2598534e+18f)   2014-05-21 02:37:00
看這描述似乎是 memory leak...
作者: azureblaze (AzureBlaze)   2014-05-21 08:28:00
11.7MB是有壓縮的的結果 要顯示一定要解壓縮所以用掉376M是正確的
作者: chchwy (mat)   2014-05-21 08:34:00
32bit程式不能用超過2G的記憶體,這是 Windows 的規定
作者: azureblaze (AzureBlaze)   2014-05-21 08:51:00
然後"剩下800M"和 "還有一塊完整超過376M"是兩回事
作者: a27417332 (等號卡比)   2014-05-21 09:08:00
然後工作管理員看到的和指標定址空間也是兩回事吧
作者: Chikei ( )   2014-05-21 12:30:00
http://goo.gl/S7UyqW OS限制就在那邊,你還是把問題描述清楚(像是為何不釋放?)讓大家幫你想想合理的設計吧。
作者: pcyu16 (._.?)   2014-05-21 12:39:00
硬體跟OS 對程式來說都算先天限制吧..不管是什麼介面 應該都沒必要同時存這麼多圖片在記憶體?還有就是這隻程式如果有現在以外的機器要用 怎麼辦...?
作者: blackwindy (黑色的風)   2014-05-21 13:11:00
你OS沒修好
作者: donkeychen (Bad_To_The_Bone)   2014-05-21 14:34:00
(本人對影像處理不太熟) 不知道有沒有相關http://goo.gl/loNDmg 也可能無關啦 畢竟我也不熟那個轉換好像是在影像處理時用的 對於不處理儲存是否能節省空間使用我不太知道 給個參考 希望有幫助
作者: googled (15357)   2014-05-21 17:44:00
查了一下影像處理的效率,似乎轉成char好像比較快@@來寫個測試的程式看看
作者: LiloHuang (十年一刻)   2014-05-21 18:20:00
處理圖片的雙重迴圈,請先跑 height 再跑 width 會較佳如果要更快可以每次處理 32bit,或者用 SIMD Intrinsic另外之前有貼過的連結,我再分享一次給你參考觀察記憶體用量請用 procexp.exe http://goo.gl/n7utTE搭配下 debug break point 來幫助自己釐清哪些階段增加真正要快就是用 OpenCL 或者 CUDA 來跑你的演算法CPU 跟 GPU 的差異 http://youtu.be/-P28LKWTzrI這就是 row major 讀取的好處,跟先跑 height 目的一樣假設你一個 pixel 就是 32bit 的話,每次就抓 32bitRGBA8888 轉 BGRA8888,抓 32bit 後再用 bitwise 操作SIMD 操作使用 MMX (64bit), SSE (128bit) 的 CPU 指令讓每次處理的資料量增加,請參考 http://goo.gl/KkIumm寫 Intrinsic 的好處是,是指 #include <xmmintrin.h>來操作那些 SIMD 的指令,而不用自己寫 inline assembly至於是不是要把資料從"空間域"轉"頻率域",要看問題類型影像處理有些細節要注意,row major 存取,記憶體對齊可以再上網多多查一些資料,大概如此。先跑 height 就是 row major 讀取,資料就是這樣擺放的這種存取方式可以有效的利用 cache,甚至做 prefetchOpenCV是個好選擇,要快可再搭配 Intel IPP,加油囉 :D
作者: donkeychen (Bad_To_The_Bone)   2014-06-05 13:54:00
推LiloHuang大大 (y)

Links booklink

Contact Us: admin [ a t ] ucptt.com