1. 對一個正在運行著的進程來說,在不到達其內存使用量邊界的情況下,擴大/縮小其cgroup分配的內存不會對它產生任何影響。
2. 在進程已經使用了一定量的內存的情況下,縮小其cgroup內存至小於已使用的內存量,有兩種結果(可通過cgroup配置,oom_kill_disable=0時殺死進程,=1時掛起進程):
A.進程被殺死
B.進程被掛起,系統向cgroup中注冊的oom處理函數發送一個oom消息;當cgroup內內存資源足夠多時,進程恢復運行;當cgroup的oom_kill_disable重新被設置為0時,進程被殺死。
3. 在給定了cgroup內存限制使用量的情況下,當cgroup內有進程申請的內存超過此限制時,結果與2相同。
4. cgroup對內存使用的限制分為物理內存限制和swap區限制,swap區的限制不能小於物理內存的限制,當進程要使用的內存超過了cgroup物理內存限制時,進程開始使用swap區(內存頁交換到磁盤),直至使用量超過swap區限制,結果與2相同。
對Java程序來說情況更復雜一些,因為JVM對進程使用的內存也有一定的控制能力
幾個相關的JVM參數:
-Xms jvm初始內存
-Xmx jvm最大內存(超出進程將拋出OOM異常)
-XX:PermSize 初始非堆內存
-XX:MaxPermSize 最大非堆內存
1. Jvm參數與cgroup對java進程的內存限制是獨立的,實際的限制是取它們的較小值。
2. 內存超出的結果不同:
Java進程使用內存超過jvm最大堆參數設置時進程終止,拋出OOM異常
Java進程使用內存超過cgroup設置時有兩種結果(同前2)
設計思路:
1. 利用jvm參數限制內存使用,容易使用的內存越界時拋出OOM異常。每個geronimo啟動時指定好Xms和Xmx,需要改變容器內存時創建新的容器同時增大/減小Xms和Xmx,然後重新啟動容器中的應用,刪除原容器。
2. 完全使用cgroup控制內存,容器使用內存越界時掛起geronimo,增大cgroup內存參數;容器一定時間內只使用少量內存時(需要額外的監控),直接減小cgroup內存參數到一個合適的值。