java隐式创建的对象

最近发现游戏服产生了大量的Long临时对象,导致YGC的频率过高。

用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发生时才回收

java隐式创建的对象_第1张图片

同样的,jdk1.5新增的方法动态参数,也会隐式的产生一个对应的数组对象

知道了问题所在就好办了,对于我的游戏来说,比较频繁的就是根据玩家的id去查询一些信息,只要把玩家的id从long改成Long,以后所有查询都通过这个唯一的Long对象来传送参数

你可能感兴趣的:(java隐式创建的对象)