最近發現遊戲服產生了大量的Long臨時對象,致使YGC的頻率太高。 java
用Jprofiler調試了下,發現了大部分是從map的get()方法產生的(遊戲裏面有些線程會比較頻繁的去一些map裏面查詢數據) 數組
就像下面的例子: 緩存
import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; public class GcTest { public static Map<Long, String> map = new HashMap<Long, String>(); public static void main(String args[]) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { test1(); test2("a", "b", "c"); } }, 100L, 100L); } public static void test1() { long id = 12345678910L; map.get(id); System.out.println("test1"); } public static void test2(String...params) { System.out.println("test2"); } }
首先map的key爲Long類型,然而傳給map.get()方法的參數倒是普通的long,這時候java內部會先隱式的調用Long.valueOf(long),臨時的產生了一個對應的Long對象,而後用它來去容器裏面查詢。
ps:對於 -128 <= x <= 127 這種比較小的數,java自己會作緩存,不會去new 一個Long對象
這個Long對象在查詢完後,就沒有引用了,一直呆在堆內存裏,直到YGC發生時纔回收 ide
一樣的,jdk1.5新增的方法動態參數,也會隱式的產生一個對應的數組對象 spa
知道了問題所在就好辦了,對於個人遊戲來講,比較頻繁的就是根據玩家的id去查詢一些信息,只要把玩家的id從long改爲Long,之後全部查詢都經過這個惟一的Long對象來傳送參數 線程