java隱式建立的對象

最近發現遊戲服產生了大量的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對象來傳送參數 線程

相關文章
相關標籤/搜索