本地緩存過期時間與JVM垃圾回收
背景:在mo的業務中,調整更長的本地緩存的有效時間,可以一定程度減少主動回源的次數,並減少YGC的頻率,但是也可能會有一些新問題。
首先要知道:
1.JVM中的堆內存是一個可以被一個進程內的所有線程共享的,而本地緩存一般就放在這塊堆內存上。
2.堆內存一般分為新生代、老生代和永久代,永久帶是方法區,不在本次討論範圍內。
3.YGC發生在新生代(創建新對象,空間不夠時觸發),FGC發生在老生代(老生代滿了才觸發)。
4.無論YGC還是FGC,都只清除JVM認為是垃圾的對象。
5.新生代又分為eden區 和S0,S1區 (S即survivor),默認的比例為8:1:1,當新生代中的對象經歷過若幹次YGC而存活,將被放入老生代(或者大對象創建時就直接進入老生代,如布局緩存)。
mo布局/活動規則/時間軸/菜單信息/菜單信息規則等 本地緩存,現在有效時間為30~60mins,如果調整為更長,如240~360min,帶來的好處:
1.減少了主動回源redis的次數;
2.因為這些緩存對象,變更的頻率並不大,可以減少YGC回收垃圾的頻率;
但是觀察mercury發現,moapi每20min就要進行一次YGC,大概3~4天進行一次FGC:
1.按照YGC的頻率,調整過長的有效時間,會導致很多本地緩存進入老生代,這些本地緩存在老生代中過期後成為垃圾,新的緩存對象又逐漸加進來,導致老生代中內存不足,導致FGC。
2.按照1中的設想,這樣調整以後,會導致FGC的頻率變高,同時老生代中的垃圾變多,會一定程度上的加長FGC的耗時(當然FGC耗時更大決定於分配的老生代的大小)。
所以,本地緩存的過期時間應該有一個調優的過程,在測試環境中,可以通過jstack來監控新老生代的情況,而生產上則應該有動態配置或一鍵回滾方案。
本地緩存過期時間與JVM垃圾回收