<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
硬體:大華sdk
軟體平臺:win10+vs2015
背景:近期在做大華工業相機SDK的採集的時候,用到Marshal.copy,將託管的程式碼轉換成非託管的指標記憶體,由於沒有及時釋放記憶體指標,導致pc的記憶體一直上漲,通過檢視程式碼之後發現是因為記憶體指標的原因,所以使用 Marshal.FreeHGlobal(pData);去釋放了託管的記憶體指標,在迴圈執行的時候才沒有導致記憶體上漲,並且通過這此的測試,發現在迴圈採集的過程中,將RGB的格式轉換成Hobject,Hobject型別的iamge影象可以不去dispose,不會導致記憶體溢位,這個和我之前的認知是有些不一樣的,原先在迴圈採集的過程中,我都會去dispose,並且防止釋放的不乾淨還會用gc.collet,但是現在測試之後發現不去釋放也可以,所以就沒有去釋放,這樣一來就方便我對記憶體裡面的資料進行提取了,而不用去擔心被dispose了。
c#有自己的記憶體回收機制,所以在c#中我們可以只new,不用關心怎樣delete,c#使用gc來清理記憶體,這部分記憶體就是managed memory,大部分時候我們工作於c#環境中,都是在使用託管記憶體,然而c#畢竟執行在c++之上,有的時候,(比如可能我們需要引入一些第三方的c++或native程式碼的庫,在Unity3d開發中很常見)我們需要直接在c#中操縱非託管的程式碼,這些non-managed memory我們就需要自己去處理他們的申請和釋放了, c# 中提供了一些介面,完成託管和非託管之間的轉換,以及對這部分記憶體的操作。
基本上有以下幾種:
比如在c#中呼叫第三方的某個c++庫,庫中有個函數是void func(float * data, int length).我們需要傳入給data的就應該是一個非託管的程式碼(why?首先傳入托管的記憶體,c#層很可能會把它gc掉,而c++還在使用,而且託管的mem它的指標地址可能會發生改變,因此直接傳給c++可能拿到的地址是錯誤的)
程式碼如下:
using System.Runtime.InteropServices; float[] _managed_data =... // this is the c# managed data GCHandle unmanaged_data_handle = GCHandle.Alloc(_managed_data, GCHandleType.Pinned); //這裡將標記_managed_data暫時不能被gc回收,並且固定物件的地址 func(unmanaged_data_handle.AddrOfPinnedObject(),_managed_data.Length);//這裡將拿到非託管記憶體的固定地址,傳給c++ unmanaged_data_handle.Free();//使用完畢後,將其handle free,這樣c#可以正常gc這塊記憶體
在c++中返回一個un-managed mem給c#使用。
有時需要在c++中分配一塊處理好的記憶體,然後返回給c#來使用,如c++中某個介面 int func(int** data) (注意這裡要使用指標的指標,因為data是得到的結果)
IntPtr unmanaged_ptr=IntPtr.Zero; //定義這個c#中用來接收c++返回資料的指標型別 int length = func(out unmanaged_ptr );//呼叫c++的函數,使unmanaged_ptr指向c++裡分配的記憶體,注意這裡用out ,才能與c++裡面的**匹配。 byte[] managed_data = new byte[length]; Marshal.Copy(unmanaged_ptr, managed_data, 0, length);//將非託管記憶體拷貝成託管記憶體,才能在c#裡面使用 Marshal.FreeHGlobal(unmanaged_ptr);//釋放非託管的記憶體
有時需要直接在c#開闢一塊非託管的記憶體,傳給c++用,這塊記憶體同樣可以在c#中用後銷燬。
程式碼如下
IntPtr unmanaged_data_prt = Marshal. AllocHGlobal(100);// 直接分配100 byte的記憶體 func(unmanaged_data_prt);//傳給c++使用 Marshal.FreeHGlobal(unmanaged_data_prt);使用後銷燬非託管記憶體
此外 Marshal類裡面還有很多處理非託管記憶體的方法。
備註
託管記憶體和非託管記憶體在c#裡面可以互相自由的轉化,主要通過Marshal類和GCHandle類,程式設計時只要注意非託管的記憶體一定要負責好釋放就可以了。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45