最新的毛片基地免费,国产国语一级毛片,免费国产成人高清在线电影,中天堂国产日韩欧美,中国国产aa一级毛片,国产va欧美va在线观看,成人不卡在线

一種內存管理裝置和方法與流程

文檔序號:11154209閱讀:324來源:國知局
一種內存管理裝置和方法與制造工藝

本發(fā)明涉及數(shù)據(jù)存儲領域,更具體地說,涉及一種內存管理裝置和方法。



背景技術:

提高硬盤寫入IO的方式無疑是批量順序寫,無論是在業(yè)界輪行的分布式文件系統(tǒng)或數(shù)據(jù),HBase,GFS和HDFS,還是以磁盤文件為持久化方式的消息隊列Kafka都采用了在內存緩存數(shù)據(jù)然后再批量寫入的策略。這一個策略的性能核心就是內存中緩沖區(qū)的設計。然而,為了滿足讀寫同步,必須要保證:(1)寫滿不寫;(2)讀空不讀(3)不丟失數(shù)據(jù)(4)不讀重復數(shù)據(jù)。為了達到這一目的,最常用的方式是JDK自帶的LinkedBlockingQueue,是一個帶鎖的消息隊列,寫入和讀出時加鎖,在滿足以上條件時,卻占用了極大的系統(tǒng)資源,成為很多對吞吐量要求很高的程序的性能瓶頸。



技術實現(xiàn)要素:

本發(fā)明要解決的技術問題在于如何避免系統(tǒng)資源的過多占用,且保證足夠的讀寫速度;針對該技術問題,提供一種內存管理裝置,包括:

創(chuàng)建模塊,用于創(chuàng)建定長數(shù)組,為定長數(shù)組的各元素分配存儲空間,所述定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構;

設置模塊,用于設置一個基于所述環(huán)形隊列的用于標識下一寫入位置的標識指針;

寫數(shù)據(jù)模塊,用于當寫數(shù)據(jù)時,通過競爭獲取所述標識指針,向所述標識指針對應的寫入位置寫入數(shù)據(jù);使所述標識指針跳轉到下一寫入位置,釋放所述標識指針;

讀數(shù)據(jù)模塊,用于當讀數(shù)據(jù)時,基于所述環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置;

確保模塊,用于在所述寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確保所述標識指針與所述當前讀取位置處于環(huán)形隊列中的不同位置。

可選的,所述定長數(shù)組的元素的數(shù)量為2的指數(shù)倍。

可選的,所述寫數(shù)據(jù)模塊還用于:通過多線程分別執(zhí)行CAS控制指令競爭獲取所述標識指針。

可選的,所述確保模塊還用于:

設置一個大于等于1的寫操作等待閾值;

在寫數(shù)據(jù)時,當寫位置差值小于等于所述寫操作等待閾值時,暫停寫數(shù)據(jù)操作,所述寫位置差值為所述標識指針沿著環(huán)形隊列的數(shù)據(jù)方向上與所述當前讀取位置之間的位置差值;

監(jiān)控所述寫位置差值,并在所述寫位置差值大于所述寫操作等待閾值時重啟寫數(shù)據(jù)操作。

可選的,所述確保模塊還用于:

設置一個大于等于1的讀操作等待閾值;

在讀數(shù)據(jù)時,當讀位置差值小于等于所述讀操作等待閾值時,暫停讀數(shù)據(jù)操作,所述讀位置差值為所述當前讀取位置沿著環(huán)形隊列的數(shù)據(jù)方向上與所述標識指針之間的位置差值;

監(jiān)控所述讀位置差值,并在所述讀位置差值大于所述讀操作等待閾值時重啟讀數(shù)據(jù)操作。

此外,還提供一種內存管理方法,包括:

創(chuàng)建定長數(shù)組,并為定長數(shù)組的各元素分配存儲空間,所述定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構;

設置一個基于所述環(huán)形隊列的用于標識下一寫入位置的標識指針;

當寫數(shù)據(jù)時,通過競爭獲取所述標識指針,向所述標識指針對應的寫入位置寫入數(shù)據(jù);使所述標識指針跳轉到下一寫入位置,釋放所述標識指針;

當讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置;

在所述寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確保所述標識指針與所述當前讀取位置處于環(huán)形隊列中的不同位置。

可選的,所述定長數(shù)組的元素的數(shù)量為2的指數(shù)倍。

可選的,所述當寫數(shù)據(jù)時,通過競爭獲取所述標識指針包括:通過多線程分別執(zhí)行CAS控制指令競爭獲取所述標識指針。

可選的,所述在寫數(shù)據(jù)過程中,確定所述標識指針與所述當前讀取位置處于環(huán)形隊列中的不同位置包括:

設置一個大于等于1的寫操作等待閾值;

在寫數(shù)據(jù)時,當寫位置差值小于等于所述寫操作等待閾值時,暫停寫數(shù)據(jù)操作,所述寫位置差值為所述標識指針沿著環(huán)形隊列的數(shù)據(jù)方向上與所述當前讀取位置之間的位置差值;

監(jiān)控所述寫位置差值,并在所述寫位置差值大于所述寫操作等待閾值時重啟寫數(shù)據(jù)操作。

可選的,所述在讀數(shù)據(jù)過程中,確定所述標識指針與所述當前讀取位置處于環(huán)形隊列中的不同位置包括:

設置一個大于等于1的讀操作等待閾值;

在讀數(shù)據(jù)時,當讀位置差值小于等于所述讀操作等待閾值時,暫停讀數(shù)據(jù)操作,所述讀位置差值為所述當前讀取位置沿著環(huán)形隊列的數(shù)據(jù)方向上與所述標識指針之間的位置差值;

監(jiān)控所述讀位置差值,并在所述讀位置差值大于所述讀操作等待閾值時重啟讀數(shù)據(jù)操作。

有益效果

本發(fā)明提供了一種內存管理裝置和方法,創(chuàng)建定長數(shù)組,為定長數(shù)組的各元素分配存儲空間,定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構,設置一個基于環(huán)形隊列的用于標識下一寫入位置的標識指針;當寫數(shù)據(jù)時,通過競爭獲取標識指針,像標識指針對應的寫入位置寫入數(shù)據(jù),讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),在讀寫的過程中,確保標識指針和當前讀取位置處于環(huán)形隊列中的不同位置。通過本發(fā)明的實施,使用標識指針來進行數(shù)據(jù)的寫入,且保證讀寫過程中標識指針和當前寫入位置不重疊,從而滿足了讀寫同步,節(jié)約了大量的系統(tǒng)資源。

附圖說明

下面將結合附圖及實施例對本發(fā)明作進一步說明,附圖中:

圖1為本發(fā)明第一實施例提供的一種內存管理裝置組成示意圖;

圖2為本發(fā)明第一實施例提供的一種環(huán)形隊列示意圖;

圖3為本發(fā)明第二實施例提供的一種寫位置差值的表現(xiàn)方式示意圖;

圖4為本發(fā)明第二實施例提供的一種讀位置差值的表現(xiàn)方式示意圖;

圖5為本發(fā)明第三實施例提供的一種內存管理方法流程圖;

圖6為本發(fā)明第四實施例提供的一種內存管理方法流程圖。

具體實施方式

應當理解,此處所描述的具體實施例僅僅用以解釋本發(fā)明,并不用于限定本發(fā)明。

第一實施例

請參考圖1,圖1為本發(fā)明第一實施例提供的一種內存管理裝置組成示意圖,包括:

創(chuàng)建模塊101,用于創(chuàng)建定長數(shù)組,為定長數(shù)組的各元素分配存儲空間,該定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構;

設置模塊102,用于設置一個基于環(huán)形隊列的用于標識下一寫入位置的標識指針;

寫數(shù)據(jù)模塊103,用于當寫數(shù)據(jù)時,通過競爭獲取標識指針,向標識指針對應的寫入位置寫入數(shù)據(jù);使標識指針跳轉到下一寫入位置,釋放標識指針;

讀數(shù)據(jù)模塊104,用于當讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置;

確保模塊105,用于在寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確保標識指針與當前讀取位置處于環(huán)形隊列中的不同位置。

本實施例中的定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構,環(huán)形隊列是在實際編程中極為有用的數(shù)據(jù)結構,它有如下特點:

它是一個首尾相連的FIFO(First In First Out,先進先出)的數(shù)據(jù)結構,采用數(shù)組的線性空間,數(shù)據(jù)組織簡單。能很快知道隊列是否是滿或是空。能以很快的速度來存取數(shù)據(jù)。

因為簡單高效的原因,甚至在硬件上都實現(xiàn)了環(huán)形隊列。

環(huán)形隊列廣泛應用于網絡數(shù)據(jù)收發(fā),和不同程序間數(shù)據(jù)交換(比如內核與應用程序大量交換數(shù)據(jù),從硬件接收大量數(shù)據(jù))均使用了環(huán)形隊列。

實際上,內存并沒有環(huán)形結構,因此環(huán)形隊列實際上是數(shù)組的線性空間來實現(xiàn)。當數(shù)據(jù)到了尾部時,它將回到0位置處理。這個轉回是通過取模操作來執(zhí)行的。因此,環(huán)形隊列邏輯上是將數(shù)組元素q[0]與q[n-1]連接,形成一個存放隊列的環(huán)形空間。請參考圖2,圖2示出了一種具有八個元素的環(huán)形隊列形態(tài)的定長數(shù)組,其中q[n-1]即為q[7]。

在實際使用中,環(huán)形隊列并沒有首尾之分,由于首尾相接,環(huán)形隊列中所存儲的數(shù)據(jù)也沒有前后的區(qū)別;然而,環(huán)形隊列的數(shù)據(jù)讀寫是有一定的方向的,雖然這個方向對于不同的環(huán)形隊列而言是不一定的,但是對于某個特定的環(huán)形隊列而言,這個方向是唯一確定的;用戶所寫入的數(shù)據(jù)是以這個確定的方向寫入,用戶讀取數(shù)據(jù)也同樣是以這個確定的方向進行讀取。

定長數(shù)組的含義在于,數(shù)組的長度,或者說數(shù)組中允許存取元素的空間的數(shù)量是固定的;請繼續(xù)參考圖2,圖2所示出的環(huán)形數(shù)組,其數(shù)組的長度是8,數(shù)組中允許存取元素的空間的數(shù)量也是8,以其中任意一個存取元素的空間作為起始元素q[0],以特定方向,圖2中的為逆時針方向,各元素的編號分別為q[1]、q[2]、q[3]、q[4]、q[5]、q[6]、q[7];當定長數(shù)組的長度不是8,是更大或者更小的數(shù)時,與為8的情況類似;如不特殊說明,本實施例中所列舉的定長數(shù)組的長度均是8。

設置模塊102用于設置一個基于該環(huán)形隊列的標識指針,用于標識下一寫入位置。在本實施例中,在定長數(shù)組中寫入數(shù)據(jù)是通過標識指針來指引的,即寫入數(shù)據(jù)是在標識指針所在的位置寫入;標識指針的邏輯是,在當前的位置寫完數(shù)據(jù)后,會進行自增,即在環(huán)形隊列的寫數(shù)據(jù)方向上自行移動,然后,在標識指針所處的新的位置上繼續(xù)寫入數(shù)據(jù)。標識指針所占用的系統(tǒng)資源極少,且無需用戶自行操作,它會自動在環(huán)形隊列中移動。

寫數(shù)據(jù)模塊103用于當寫數(shù)據(jù)時,通過競爭獲取標識指針,向標識指針對應的寫入位置寫入數(shù)據(jù)。當不止一個數(shù)據(jù)要寫入時,在同一個存儲位置一般只存儲一個對象寫入的數(shù)據(jù),那么,不同的對象之間就需要通過競爭,來獲取標識指針,或者說獲取標識指針的使用權,使該對象能夠在標識指針所在的位置寫入數(shù)據(jù)。

在當前位置的數(shù)據(jù)寫完之后,標識指針跳轉到下一寫入位置,釋放標識指針。其中,釋放標識指針,或者說釋放標識指針的控制權,在前一次的數(shù)據(jù)寫入完成后,釋放的標識指針會自動的沿著數(shù)據(jù)寫入的方向跳轉到下一寫入位置,等待下一數(shù)據(jù)的寫入。

讀數(shù)據(jù)模塊104用于當讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置?;诃h(huán)形隊列依次順序讀取數(shù)據(jù),指的就是在環(huán)形隊列中,數(shù)據(jù)的讀取是按照一個特定的方向來的,對于一個特定的環(huán)形隊列而言,這個方向是確定的,與寫數(shù)據(jù)的方向一致。

確保模塊105,用于在寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確定標識指針和當前讀取位置處于環(huán)形隊列中的不同位置。由于在數(shù)據(jù)讀寫的過程中,有著寫滿不寫,讀空不讀的要求,即環(huán)形隊列中即將在下一個位置寫數(shù)據(jù)時,該下一個位置的數(shù)據(jù)仍然未被讀取,那么就不應再寫;以及在環(huán)形隊列中,即將讀取下一位置的數(shù)據(jù)時,下一位置的數(shù)據(jù)為空或者尚未寫完,那么就不應再讀。如果在下一位置的數(shù)據(jù)仍未被讀取時寫入數(shù)據(jù)的話,那么就會導致數(shù)據(jù)丟失;如果在下一位置的數(shù)據(jù)為空或者尚未寫完時讀取數(shù)據(jù)的話,就會讀取到空的數(shù)據(jù),浪費系統(tǒng)資源和時間。

而正常而言,數(shù)據(jù)讀寫的過程中,一個數(shù)據(jù)總是先被寫入之后,再被讀取,換言之,對于一個數(shù)據(jù)而言,寫入在先,讀取在后,在環(huán)形隊列中,總是先寫的數(shù)據(jù)先被讀取,那么,在滿足寫滿不寫,讀空不讀時,標識指針和當前讀取位置總是處于環(huán)形隊列中的不同位置的。

本實施例提供了一種內存管理裝置,包括創(chuàng)建模塊、設置模塊、寫數(shù)據(jù)模塊、讀數(shù)據(jù)模塊以及確保模塊,通過實施例的實施,實現(xiàn)了使用標識指針來進行數(shù)據(jù)的寫入,且保證讀寫過程中標識指針和當前寫入位置不重疊,滿足和讀寫同步,節(jié)約了大量的系統(tǒng)資源。

第二實施例

請繼續(xù)參考圖1,圖1為本發(fā)明第二實施例提供的一種內存管理裝置組成示意圖,包括:

創(chuàng)建模塊101,用于創(chuàng)建定長數(shù)組,為定長數(shù)組的各元素分配存儲空間,該定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構;

設置模塊102,用于設置一個基于環(huán)形隊列的用于標識下一寫入位置的標識指針;

寫數(shù)據(jù)模塊103,用于當寫數(shù)據(jù)時,通過競爭獲取標識指針,向標識指針對應的寫入位置寫入數(shù)據(jù);使標識指針跳轉到下一寫入位置,釋放標識指針;

讀數(shù)據(jù)模塊104,用于當讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置;

確保模塊105,用于在寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確保標識指針與當前讀取位置處于環(huán)形隊列中的不同位置。

其中,在本實施例中,關于定長數(shù)組的大小的選擇方面有一定的要求,由于在環(huán)形隊列中會用到取余操作,在大部分處理器上,取余操作并不高效,因此,在本實施例中,定長數(shù)組的元素的數(shù)量為2的指數(shù)倍,這樣,計算余數(shù)只需要通過為操作index&(size-1)就能夠得到實際的index。對外只有一個變量,那就是隊尾元素的下標:cursor,這也避免了對head/tail這兩個變量的操作和協(xié)同。

在本實施例中,寫數(shù)據(jù)模塊103還用于:通過多線程分別執(zhí)行CAS控制指令競爭獲取標識指針。在實際寫數(shù)據(jù)的過程中,在同一時間可能并不止有一個即將執(zhí)行的寫入操作,即進行寫操作的對象并不止一個;如果兩個或以上的對象同時都想寫入數(shù)據(jù),則他們會同時執(zhí)行CAS指令,具體為CAS(slot,slot+1),然后執(zhí)行成功的競爭成功,獲取標識指針,或者說是獲取標識指針對應的寫入位置的存儲權,獲取該存儲權的對象就可以將數(shù)據(jù)寫入,其他的未獲取成功的則需要繼續(xù)下一個CAS指令申請之后的標識指針。在這一過程中,一般并不需要用到鎖,使用的是系統(tǒng)的CAS指令。

在很多時候會有多個對象去搶數(shù)組上的同一個位置,在一般的java程序中,是通過加鎖來實現(xiàn),但本實施例是通過CAS來實現(xiàn)的,多個會去競爭,但不會存在兩個同時搶到,搶不到的就搶下一個位置。讀寫雙方都要檢查對方的位置,防止超過對方。在本實施例中,檢查的策略可以包括主動檢查,比如按照一定的時間間隔周期性的檢查對方的位置,或者等待對方的通知,如設置一道指令,令對方讀/寫到環(huán)形隊列的某一位置即發(fā)送通知。

在本實施例中,確保模塊105還用于:設置一個大于等于1的寫操作等待閾值;

在寫數(shù)據(jù)時,當寫位置差值小于等于寫操作等待閾值時,暫停寫數(shù)據(jù)操作,其中,寫位置差值為標識指針沿著環(huán)形隊列的數(shù)據(jù)方向上與當前讀取位置之間的位置差值;

監(jiān)控寫位置差值,并在寫位置差值大于寫操作等待閾值時重啟寫數(shù)據(jù)操作。

也就是說,確保模塊105為了確保在寫數(shù)據(jù)時,確保標識指針與當前讀取位置處于環(huán)形隊列中的不同位置,首先,設置一個大于等于1的寫操作等待閾值,而寫位置差值則是標識指針,在沿著環(huán)形隊列的數(shù)據(jù)方向上與當前讀取位置之間的位置差值;通俗的講,就是標識指針與當前讀取位置之間的間隔,而這個間隔是從標識指針到下一寫入位置方向上所得的,請參考圖3,圖3示出了一種寫位置差值的計算方式,或者說是表現(xiàn)方式。從圖3中可以看出,讀數(shù)據(jù)的方向和寫數(shù)據(jù)的方向是一致的,當寫數(shù)據(jù)的速度過快時,標識指針的位置就可能達到或者超過當前讀取位置。因此,設置一個寫操作等待閾值,這個閾值至少為1,即標識指針與當前讀取位置之間至少間隔一個位置,而具體的寫操作等待閾值可以基于環(huán)形隊列的長度、數(shù)據(jù)量的大小、讀寫的速度等等參數(shù)進行設置;當標識指針所處的位置與當前讀取位置之間的差值小于或等于寫操作等待閾值時,暫停寫數(shù)據(jù)操作,即不再進行寫數(shù)據(jù)操作;與此同時,實時監(jiān)控寫位置差值,在寫位置差值大于寫操作等待閾值時,重啟寫數(shù)據(jù)操作。

在本實施例中,確保模塊105還用于:設置一個大于等于1的讀操作等待閾值;

在讀數(shù)據(jù)時,當讀位置差值小于等于讀操作等待閾值時,暫停讀數(shù)據(jù)操作,其中,讀位置差值為當前讀取位置沿著環(huán)形隊列的數(shù)據(jù)方向上與標識指針之間的位置差值;

監(jiān)控讀位置差值,并在讀位置差值大于讀操作等待閾值時重啟讀數(shù)據(jù)操作。

也就是說,確保模塊105為了確保在讀數(shù)據(jù)時,確保標識指針與當前讀取位置處于環(huán)形隊列中的不同位置,首先,設置一個大于等于1的讀操作等待閾值,而讀位置差值則是,在沿著環(huán)形隊列的數(shù)據(jù)方向上與標識指針之間的位置差值;通俗的講,就是當前讀取位置與標識指針之間的間隔,而這個間隔是從當前讀取位置到下一讀取位置方向上所得的,請參考圖4,圖4示出了一種讀位置差值的計算方式,或者說是表現(xiàn)方式。從圖4中可以看出,讀數(shù)據(jù)的方向和寫數(shù)據(jù)的方向是一致的,當讀數(shù)據(jù)的速度過快時,當前讀取位置就可能達到或超過標識指針所在的位置。因此,設置一個讀操作等待閾值,這個閾值至少為1,即當前讀取位置與標識指針之間至少間隔一個位置,而具體的讀操作等待閾值可以基于環(huán)形隊列的長度、數(shù)據(jù)量的大小、讀寫的速度等等參數(shù)進行設置;當當前讀取位置與標識指針所處的位置之間的差值小于或等于讀操作等待閾值時,暫停讀數(shù)據(jù)操作,即不再進行讀數(shù)據(jù)操作;與此同時,實時監(jiān)控讀位置差值,在讀位置差值大于讀操作等待閾值時,重啟讀數(shù)據(jù)操作。

值得一提的是,在本實施例中,寫操作和讀操作之間,若偏重于寫操作,即以寫操作為主,那么,應該設置寫操作等待閾值較小,若偏重于讀操作,即以讀操作為主,那么,應該設置讀操作等待閾值較小。由于本實施例中的數(shù)組是定長數(shù)組,因此,在為了保證其中一個效果較好時設置更小的讀/寫操作等待閾值時,另一個寫/讀操作等待閾值就相應的設置為較大,具體如何權衡可以根據(jù)環(huán)形隊列的長度、數(shù)據(jù)量的大小以及讀寫的速度來決定。

此外,由于本實施例中的基于環(huán)形隊列的定長數(shù)組已經進行了編碼,而讀寫操作一般都是根據(jù)編碼的順序而來,如寫數(shù)據(jù)是從q[0]開始,經過q[1]、q[2]等等到q[7],然后再回到q[0]進入一個循環(huán);而讀數(shù)據(jù)亦如是,因此,若是用序號進行寫位置差值和讀位置差值的計算,那么沿著環(huán)形隊列的數(shù)據(jù)方向,前者與后者之間的差值應該為負值,因此,本實施例中的寫位置差值的準確表述應該是,標識指針所在位置沿環(huán)形隊列的數(shù)據(jù)方向上與當前讀取位置之間間隔的元素的數(shù)目,讀位置差值的準確表述應該是,當前讀取位置沿環(huán)形隊列的數(shù)據(jù)方向上與標識指針所在位置之間間隔的元素的數(shù)目。

本實施例提供了一種內存管理裝置,包括創(chuàng)建模塊、設置模塊、寫數(shù)據(jù)模塊、讀數(shù)據(jù)模塊以及確保模塊,通過實施例的實施,實現(xiàn)了使用標識指針來進行數(shù)據(jù)的寫入,且保證讀寫過程中標識指針和當前寫入位置不重疊,滿足和讀寫同步,節(jié)約了大量的系統(tǒng)資源。

第三實施例

請參考圖5,圖5為本發(fā)明第三實施例提供的一種內存管理方法流程圖,包括:

S501、創(chuàng)建定長數(shù)組,并為定長數(shù)組的各元素分配分配存儲空間,所述定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構;

S502、設置一個基于環(huán)形隊列的用于標識下一寫入位置的標識指針;

S503、當寫數(shù)據(jù)時,通過競爭獲取標識指針,向標識指針對應的寫入位置寫入數(shù)據(jù);使標識指針跳轉到下一寫入位置,釋放標識指針;

S504、當讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置;

其中,在寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確保標識指針與當前讀取位置處于環(huán)形隊列中的不同位置。

本實施例中的定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構,環(huán)形隊列是在實際編程中極為有用的數(shù)據(jù)結構,它有如下特點:

它是一個首尾相連的FIFO(First In First Out,先進先出)的數(shù)據(jù)結構,采用數(shù)組的線性空間,數(shù)據(jù)組織簡單。能很快知道隊列是否是滿或是空。能以很快的速度來存取數(shù)據(jù)。

因為簡單高效的原因,甚至在硬件上都實現(xiàn)了環(huán)形隊列。

環(huán)形隊列廣泛應用于網絡數(shù)據(jù)收發(fā),和不同程序間數(shù)據(jù)交換(比如內核與應用程序大量交換數(shù)據(jù),從硬件接收大量數(shù)據(jù))均使用了環(huán)形隊列。

實際上,內存并沒有環(huán)形結構,因此環(huán)形隊列實際上是數(shù)組的線性空間來實現(xiàn)。當數(shù)據(jù)到了尾部時,它將回到0位置處理。這個轉回是通過取模操作來執(zhí)行的。因此,環(huán)形隊列邏輯上是將數(shù)組元素q[0]與q[n-1]連接,形成一個存放隊列的環(huán)形空間。請參考圖2,圖2示出了一種具有八個元素的環(huán)形隊列形態(tài)的定長數(shù)組,其中q[n-1]即為q[7]。

在實際使用中,環(huán)形隊列并沒有首尾之分,由于首尾相接,環(huán)形隊列中所存儲的數(shù)據(jù)也沒有前后的區(qū)別;然而,環(huán)形隊列的數(shù)據(jù)讀寫是有一定的方向的,雖然這個方向對于不同的環(huán)形隊列而言是不一定的,但是對于某個特定的環(huán)形隊列而言,這個方向是唯一確定的;用戶所寫入的數(shù)據(jù)是以這個確定的方向寫入,用戶讀取數(shù)據(jù)也同樣是以這個確定的方向進行讀取。

定長數(shù)組的含義在于,數(shù)組的長度,或者說數(shù)組中允許存取元素的空間的數(shù)量是固定的;請繼續(xù)參考圖2,圖2所示出的環(huán)形數(shù)組,其數(shù)組的長度是8,數(shù)組中允許存取元素的空間的數(shù)量也是8,以其中任意一個存取元素的空間作為起始元素q[0],以特定方向,圖2中的為逆時針方向,各元素的編號分別為q[1]、q[2]、q[3]、q[4]、q[5]、q[6]、q[7];當定長數(shù)組的長度不是8,是更大或者更小的數(shù)時,與為8的情況類似;如不特殊說明,本實施例中所列舉的定長數(shù)組的長度均是8。

其中,在本實施例中,關于定長數(shù)組的大小的選擇方面有一定的要求,由于在環(huán)形隊列中會用到取余操作,在大部分處理器上,取余操作并不高效,因此,在本實施例中,定長數(shù)組的元素的數(shù)量為2的指數(shù)倍,這樣,計算余數(shù)只需要通過為操作index&(size-1)就能夠得到實際的index。對外只有一個變量,那就是隊尾元素的下標:cursor,這也避免了對head/tail這兩個變量的操作和協(xié)同。

S502中,設置一個基于該環(huán)形隊列的標識指針,用于標識下一寫入位置。在本實施例中,在定長數(shù)組中寫入數(shù)據(jù)是通過標識指針來指引的,即寫入數(shù)據(jù)是在標識指針所在的位置寫入;標識指針的邏輯是,在當前的位置寫完數(shù)據(jù)后,會進行自增,即在環(huán)形隊列的寫數(shù)據(jù)方向上自行移動,然后,在標識指針所處的新的位置上繼續(xù)寫入數(shù)據(jù)。標識指針所占用的系統(tǒng)資源極少,且無需用戶自行操作,它會自動在環(huán)形隊列中移動。

S503中,當寫數(shù)據(jù)時,通過競爭獲取標識指針,向標識指針對應的寫入位置寫入數(shù)據(jù)。當不止一個數(shù)據(jù)要寫入時,在同一個存儲位置一般只存儲一個對象寫入的數(shù)據(jù),那么,不同的對象之間就需要通過競爭,來獲取標識指針,或者說獲取標識指針的使用權,使該對象能夠在標識指針所在的位置寫入數(shù)據(jù)。

通過多線程分別執(zhí)行CAS控制指令競爭獲取標識指針。在實際寫數(shù)據(jù)的過程中,在同一時間可能并不止有一個即將執(zhí)行的寫入操作,即進行寫操作的對象并不止一個;如果兩個或以上的對象同時都想寫入數(shù)據(jù),則他們會同時執(zhí)行CAS指令,具體為CAS(slot,slot+1),然后執(zhí)行成功的競爭成功,獲取標識指針,或者說是獲取標識指針對應的寫入位置的存儲權,獲取該存儲權的對象就可以將數(shù)據(jù)寫入,其他的未獲取成功的則需要繼續(xù)下一個CAS指令申請之后的標識指針。在這一過程中,一般并不需要用到鎖,使用的是系統(tǒng)的CAS指令。

在很多時候會有多個對象去搶數(shù)組上的同一個位置,在一般的java程序中,是通過加鎖來實現(xiàn),但本實施例是通過CAS來實現(xiàn)的,多個會去競爭,但不會存在兩個同時搶到,搶不到的就搶下一個位置。讀寫雙方都要檢查對方的位置,防止超過對方。在本實施例中,檢查的策略可以包括主動檢查,比如按照一定的時間間隔周期性的檢查對方的位置,或者等待對方的通知,如設置一道指令,令對方讀/寫到環(huán)形隊列的某一位置即發(fā)送通知。

在當前位置的數(shù)據(jù)寫完之后,標識指針跳轉到下一寫入位置,釋放標識指針。其中,釋放標識指針,或者說釋放標識指針的控制權,在前一次的數(shù)據(jù)寫入完成后,釋放的標識指針會自動的沿著數(shù)據(jù)寫入的方向跳轉到下一寫入位置,等待下一數(shù)據(jù)的寫入。

S504中,當讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),并更新當前讀取位置。基于環(huán)形隊列依次順序讀取數(shù)據(jù),指的就是在環(huán)形隊列中,數(shù)據(jù)的讀取是按照一個特定的方向來的,對于一個特定的環(huán)形隊列而言,這個方向是確定的,與寫數(shù)據(jù)的方向一致。

在寫數(shù)據(jù)和讀數(shù)據(jù)的過程中,確定標識指針和當前讀取位置處于環(huán)形隊列中的不同位置。由于在數(shù)據(jù)讀寫的過程中,有著寫滿不寫,讀空不讀的要求,即環(huán)形隊列中即將在下一個位置寫數(shù)據(jù)時,該下一個位置的數(shù)據(jù)仍然未被讀取,那么就不應再寫;以及在環(huán)形隊列中,即將讀取下一位置的數(shù)據(jù)時,下一位置的數(shù)據(jù)為空或者尚未寫完,那么就不應再讀。如果在下一位置的數(shù)據(jù)仍未被讀取時寫入數(shù)據(jù)的話,那么就會導致數(shù)據(jù)丟失;如果在下一位置的數(shù)據(jù)為空或者尚未寫完時讀取數(shù)據(jù)的話,就會讀取到空的數(shù)據(jù),浪費系統(tǒng)資源和時間。

而正常而言,數(shù)據(jù)讀寫的過程中,一個數(shù)據(jù)總是先被寫入之后,再被讀取,換言之,對于一個數(shù)據(jù)而言,寫入在先,讀取在后,在環(huán)形隊列中,總是先寫的數(shù)據(jù)先被讀取,那么,在滿足寫滿不寫,讀空不讀時,標識指針和當前讀取位置總是處于環(huán)形隊列中的不同位置的。

本實施例中,為了確保標識指針和當前讀取位置總是處于環(huán)形隊列中的不同位置,還可以包括:

設置一個大于等于1的寫操作等待閾值;

在寫數(shù)據(jù)時,當寫位置差值小于等于寫操作等待閾值時,暫停寫數(shù)據(jù)操作,其中,寫位置差值為標識指針沿著環(huán)形隊列的數(shù)據(jù)方向上與當前讀取位置之間的位置差值;

監(jiān)控寫位置差值,并在寫位置差值大于寫操作等待閾值時重啟寫數(shù)據(jù)操作。

也就是說,首先,設置一個大于等于1的寫操作等待閾值,而寫位置差值則是標識指針,在沿著環(huán)形隊列的數(shù)據(jù)方向上與當前讀取位置之間的位置差值;通俗的講,就是標識指針與當前讀取位置之間的間隔,而這個間隔是從標識指針到下一寫入位置方向上所得的,請參考圖3,圖3示出了一種寫位置差值的計算方式,或者說是表現(xiàn)方式。從圖3中可以看出,讀數(shù)據(jù)的方向和寫數(shù)據(jù)的方向是一致的,當寫數(shù)據(jù)的速度過快時,標識指針的位置就可能達到或者超過當前讀取位置。因此,設置一個寫操作等待閾值,這個閾值至少為1,即標識指針與當前讀取位置之間至少間隔一個位置,而具體的寫操作等待閾值可以基于環(huán)形隊列的長度、數(shù)據(jù)量的大小、讀寫的速度等等參數(shù)進行設置;當標識指針所處的位置與當前讀取位置之間的差值小于或等于寫操作等待閾值時,暫停寫數(shù)據(jù)操作,即不再進行寫數(shù)據(jù)操作;與此同時,實時監(jiān)控寫位置差值,在寫位置差值大于寫操作等待閾值時,重啟寫數(shù)據(jù)操作。

本實施例中,為了確保標識指針和當前讀取位置總是處于環(huán)形隊列中的不同位置,還可以包括:

設置一個大于等于1的讀操作等待閾值;

在讀數(shù)據(jù)時,當讀位置差值小于等于讀操作等待閾值時,暫停讀數(shù)據(jù)操作,其中,讀位置差值為當前讀取位置沿著環(huán)形隊列的數(shù)據(jù)方向上與標識指針之間的位置差值;

監(jiān)控讀位置差值,并在讀位置差值大于讀操作等待閾值時重啟讀數(shù)據(jù)操作。

也就是說,首先,設置一個大于等于1的讀操作等待閾值,而讀位置差值則是,在沿著環(huán)形隊列的數(shù)據(jù)方向上與標識指針之間的位置差值;通俗的講,就是當前讀取位置與標識指針之間的間隔,而這個間隔是從當前讀取位置到下一讀取位置方向上所得的,請參考圖4,圖4示出了一種讀位置差值的計算方式,或者說是表現(xiàn)方式。從圖4中可以看出,讀數(shù)據(jù)的方向和寫數(shù)據(jù)的方向是一致的,當讀數(shù)據(jù)的速度過快時,當前讀取位置就可能達到或超過標識指針所在的位置。因此,設置一個讀操作等待閾值,這個閾值至少為1,即當前讀取位置與標識指針之間至少間隔一個位置,而具體的讀操作等待閾值可以基于環(huán)形隊列的長度、數(shù)據(jù)量的大小、讀寫的速度等等參數(shù)進行設置;當當前讀取位置與標識指針所處的位置之間的差值小于或等于讀操作等待閾值時,暫停讀數(shù)據(jù)操作,即不再進行讀數(shù)據(jù)操作;與此同時,實時監(jiān)控讀位置差值,在讀位置差值大于讀操作等待閾值時,重啟讀數(shù)據(jù)操作。

值得一提的是,在本實施例中,寫操作和讀操作之間,若偏重于寫操作,即以寫操作為主,那么,應該設置寫操作等待閾值較小,若偏重于讀操作,即以讀操作為主,那么,應該設置讀操作等待閾值較小。由于本實施例中的數(shù)組是定長數(shù)組,因此,在為了保證其中一個效果較好時設置更小的讀/寫操作等待閾值時,另一個寫/讀操作等待閾值就相應的設置為較大,具體如何權衡可以根據(jù)環(huán)形隊列的長度、數(shù)據(jù)量的大小以及讀寫的速度來決定。

本實施例提供了一種內存管理方法,創(chuàng)建定長數(shù)組,為定長數(shù)組的各元素分配存儲空間,定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構,設置一個基于環(huán)形隊列的用于標識下一寫入位置的標識指針;當寫數(shù)據(jù)時,通過競爭獲取標識指針,像標識指針對應的寫入位置寫入數(shù)據(jù),讀數(shù)據(jù)時,基于環(huán)形隊列依次順序讀取數(shù)據(jù),在讀寫的過程中,確保標識指針和當前讀取位置處于環(huán)形隊列中的不同位置。通過本發(fā)明的實施,使用標識指針來進行數(shù)據(jù)的寫入,且保證讀寫過程中標識指針和當前寫入位置不重疊,從而滿足了讀寫同步,節(jié)約了大量的系統(tǒng)資源。

第四實施例

請參考圖6,圖6為本發(fā)明第四實施例提供的一種內存管理方法流程圖。

本實施例以生產者和消費者為例,對數(shù)據(jù)的讀寫做進一步說明,其中生產者一般作為寫入數(shù)據(jù)的對象,而消費者則作為讀取數(shù)據(jù)的對象。

S601、創(chuàng)建定長數(shù)組,為定長數(shù)組的個元素分配存儲空間,定長數(shù)組使用環(huán)形隊列數(shù)據(jù)結構;

S602、設置一個基于環(huán)形隊列的用于標識下一寫入位置的標識指針;

S603、生產者通過競爭獲取標識指針,向標識指針對應的寫入位置寫入數(shù)據(jù);

S604、消費者基于環(huán)形隊列依次順序讀取數(shù)據(jù),更新當前讀取位置。

其中,生產者和消費者讀寫數(shù)據(jù)的過程中,確保標識指針和當前讀取位置處于環(huán)形隊列中的不同位置。

在實際使用中,環(huán)形隊列并沒有首尾之分,由于首尾相接,環(huán)形隊列中所存儲的數(shù)據(jù)也沒有前后的區(qū)別;然而,環(huán)形隊列的數(shù)據(jù)讀寫是有一定的方向的,雖然這個方向對于不同的環(huán)形隊列而言是不一定的,但是對于某個特定的環(huán)形隊列而言,這個方向是唯一確定的;生產者所寫入的數(shù)據(jù)是以這個確定的方向寫入,消費者讀取數(shù)據(jù)也同樣是以這個確定的方向進行讀取。

關于定長數(shù)組的大小的選擇方面有一定的要求,由于在環(huán)形隊列中會用到取余操作,在大部分處理器上,取余操作并不高效,因此,在本實施例中,定長數(shù)組的元素的數(shù)量為2的指數(shù)倍,這樣,計算余數(shù)只需要通過為操作index&(size-1)就能夠得到實際的index。對外只有一個變量,那就是隊尾元素的下標:cursor,這也避免了對head/tail這兩個變量的操作和協(xié)同。

設置一個基于該環(huán)形隊列的標識指針,用于標識下一寫入位置。在本實施例中,在定長數(shù)組中寫入數(shù)據(jù)是通過標識指針來指引的,即寫入數(shù)據(jù)是在標識指針所在的位置寫入;標識指針的邏輯是,在當前的位置寫完數(shù)據(jù)后,會進行自增,即在環(huán)形隊列的寫數(shù)據(jù)方向上自行移動,然后,在標識指針所處的新的位置上繼續(xù)寫入數(shù)據(jù)。標識指針所占用的系統(tǒng)資源極少,且無需用戶自行操作,它會自動在環(huán)形隊列中移動。

通過多線程分別執(zhí)行CAS控制指令競爭獲取標識指針。在實際寫數(shù)據(jù)的過程中,在同一時間可能并不止有一個即將執(zhí)行的寫入操作,即進行寫操作的生產者并不止一個;如果兩個或以上的生產者同時都想寫入數(shù)據(jù),則他們會同時執(zhí)行CAS指令,具體為CAS(slot,slot+1),然后執(zhí)行成功的競爭成功,獲取標識指針,或者說是獲取標識指針對應的寫入位置的存儲權,獲取該存儲權的對象就可以將數(shù)據(jù)寫入,其他的未獲取成功的生產者則需要繼續(xù)下一個CAS指令申請之后的標識指針。在這一過程中,一般并不需要用到鎖,使用的是系統(tǒng)的CAS指令。

在很多時候會有多個生產者去搶數(shù)組上的同一個位置,在一般的java程序中,是通過加鎖來實現(xiàn),但本實施例是通過CAS來實現(xiàn)的,多個會去競爭,但不會存在兩個同時搶到的情況,搶不到的就搶下一個位置。

消費者基于環(huán)形隊列依次順序讀取數(shù)據(jù),指的就是在環(huán)形隊列中,數(shù)據(jù)的讀取是按照一個特定的方向來的,對于一個特定的環(huán)形隊列而言,這個方向是確定的,與寫數(shù)據(jù)的方向一致。

為了防止生產者生產過快,在環(huán)形隊列中覆蓋消費者的數(shù)據(jù),生成者要對消費者的消費情況進行跟蹤,即讀取各消費者當前的讀取位置。

消費者需要等待有新元素進入方能繼續(xù)讀取,也就是說標識指針大于當前讀取位置。等待策略有多種,可以選擇sleep wait可以根據(jù)場景選擇不同的等待策略。

生產者和消費者雙方都要檢查對方的位置,防止超過對方。在本實施例中,檢查的策略可以包括主動檢查,比如按照一定的時間間隔周期性的檢查對方的位置,或者等待對方的通知,如設置一道指令,令對方讀/寫到環(huán)形隊列的某一位置即發(fā)送通知。比如,消費者可以說“當你的位置比X大的時候請告訴我”,說明X之前的節(jié)點已經被生產者寫入了數(shù)據(jù),而且消費者對這些節(jié)點的操作是讀而不是寫,因此訪問不用加鎖。

需要說明的是,在本文中,術語“包括”、“包含”或者其任何其他變體意在涵蓋非排他性的包含,從而使得包括一系列要素的過程、方法、物品或者裝置不僅包括那些要素,而且還包括沒有明確列出的其他要素,或者是還包括為這種過程、方法、物品或者裝置所固有的要素。在沒有更多限制的情況下,由語句“包括一個……”限定的要素,并不排除在包括該要素的過程、方法、物品或者裝置中還存在另外的相同要素。

上述本發(fā)明實施例序號僅僅為了描述,不代表實施例的優(yōu)劣。

通過以上的實施方式的描述,本領域的技術人員可以清楚地了解到上述實施例方法可借助軟件加必需的通用硬件平臺的方式來實現(xiàn),當然也可以通過硬件,但很多情況下前者是更佳的實施方式。基于這樣的理解,本發(fā)明的技術方案本質上或者說對現(xiàn)有技術做出貢獻的部分可以以軟件產品的形式體現(xiàn)出來,該計算機軟件產品存儲在一個存儲介質(如ROM/RAM、磁碟、光盤)中,包括若干指令用以使得一臺終端設備(可以是手機,計算機,服務器,空調器,或者網絡設備等)執(zhí)行本發(fā)明各個實施例所述的方法。

上面結合附圖對本發(fā)明的實施例進行了描述,但是本發(fā)明并不局限于上述的具體實施方式,上述的具體實施方式僅僅是示意性的,而不是限制性的,本領域的普通技術人員在本發(fā)明的啟示下,在不脫離本發(fā)明宗旨和權利要求所保護的范圍情況下,還可做出很多形式,這些均屬于本發(fā)明的保護之內。

當前第1頁1 2 3 
網友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1