2009-10-19 27 views
2

我有一個Linux系統V IPC共享內存段,由一個進程填充並被許多其他人讀取。所有進程都以類的形式使用共享內存段的接口,該類負責查看,附加和分離段,作爲其構造器/析構器方法的一部分。未解釋的Linux系統V IPC共享內存段被標記爲銷燬

這裏的問題是,我不時看到細分市場已經「分裂」。我在這裏的意思是,在「ipcs -m -s」輸出中看到我已經列出了兩個分段:一個被標記爲銷燬,但仍然附着一些進程,另一個顯示爲獲得所有新的嘗試附加到該段。但是,我從來沒有真正要求內核銷燬該段。這裏發生了什麼事?!

還有一點需要注意的是,不幸的是,這個系統運行在內存部門嚴重過度。有1 GB物理內存,沒有交換,並且/ proc/meminfo中的Committed_AS報告大約2.5GB的提交內存。幸運的是系統進程實際上並沒有使用這麼多的內存......他們只是要求它(我仍然有大約660MB的「free」內存,正如vmstat所報告的那樣)。雖然我知道這是遠遠不夠理想的,但目前我無法對超載內存做任何事情。但是,瀏覽內核/ libc源代碼時,我沒有看到任何內容會將共享內存段標記爲除用戶請求之外的任何原因刪除(但也許我錯過了它隱藏在某處)。

僅供參考這裏的共享內存接口類的構造函數:

const char* shm_ftok_pathname = "/usr/bin"; 
int shm_ftok_proj_id = 21; 

// creates a key from a file path so different processes will get same key 
key_t m_shm_key = ftok(shm_ftok_pathname, shm_ftok_proj_id); 

if (m_shm_key == -1) 
{ 
    fprintf(stderr,"Couldn't get the key for the shared memory\n%s\n",strerror(errno)); 
    exit (status); 
} 

m_shm_id = shmget(m_shm_key, sizeof(shm_data_s), (IPC_CREAT | 0666)); 

if (m_shm_id < 0) 
{ 
    fprintf(stderr,"Couldn't get the shared memory ID\nerrno = %s \n",strerror(errno)); 
    exit (status); 
} 

// get a ptr to shared memory, which is a shared mem struct 
// second arg of 0 says let OS choose shm address 
m_shm_data_ptr = (shm_data_s *)shmat(m_shm_id, 0, 0); 

if ((int)m_shm_data_ptr == -1) 
{ 
    fprintf(stderr,"Couldn't get the shared memory pointer\n"); 
    exit (status); 
} 

這是我的UNAME輸出: Linux的2.6.18-5-686#1 SMP週五6月1日○點47分00秒UTC 2007 i686 GNU/Linux

+0

不知您是否需要擔心Linux OOM殺手因爲內存不足?谷歌它... –

+0

感謝您的意見,但我不相信我遇到了OOM問題。首先,我沒有看到任何被殺死的進程的證據,也不會預料到,因爲我從來沒有真正用完內存(即,雖然聚合內存請求確實比可用內存要多,因爲進程並不是實際上使用內存有很多可用的頁面)。即使一個進程被殺害,我也沒有看到我在共享內存設置中做了什麼會導致內存「分裂」。 –

回答

1

我的第一個猜測是你可能打電話給shmctl(..., IPC_RMID, ...)某處。

你可以顯示共享內存接口類的析構函數嗎?

+1

+1同意,必須在某處調用shmctl(... IPC_RMID,...)。這是有道理的,因爲在descructor ...你確定析構函數沒有被調用? –

+0

實際上,在第一次連接之後調用shmctl(... IPC_RMID ...)是很典型的,所以當沒有更多引用時,段會自動刪除。 – ninjalj

0

內核將段標記爲刪除的唯一原因是明確的用戶調用。可能您可以嘗試strace/truss(在solaris中)以查明是否有用戶調用該函數,在上面1中提到。

拉曼Chalotra

+0

實際上,刪除的唯一真正原因是該段被標記爲刪除_並且沒有引用。 – ninjalj