import java.util.Calendar;
import java.util.concurrent.atomic.AtomicLong;
public class CalendarLeakTest {
private static Calendar cal = Calendar.getInstance();
public final static long getMsgid(long GwSeq) {
//函數內調用,會造成內存泄露
//Calendar cal = Calendar.getInstance();
long res = 0;
cal.setTimeInMillis(System.currentTimeMillis());
long month = cal.get(Calendar.MONTH) + 1;
long day = cal.get(Calendar.DAY_OF_MONTH);
long hour = cal.get(Calendar.HOUR_OF_DAY);
long minute = cal.get(Calendar.MINUTE);
long seconds = cal.get(Calendar.SECOND);
res = month << 60 | day << 55 | hour << 50 | minute << 44 | seconds << 38 | GwSeq << 16 | getMsgIdSeq();
return res;
}
private static AtomicLong msgidseq = new AtomicLong(100l);
/**
* 自增循環使用(msgid)
*/
private final static long getMsgIdSeq() {
long next = msgidseq.incrementAndGet();
if (next > 65535) {
synchronized (msgidseq) {
if (msgidseq.get() > 65535) {
msgidseq.set(100);
next = msgidseq.incrementAndGet();
} else {
next = msgidseq.incrementAndGet();
}
}
}
return next;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
getMsgid(123);
}
System.out.println(System.currentTimeMillis()-start+"ms");
}
}
以上代碼,alendar.getInstance() 在方法外聲明創建 2核4線程 處理時間爲1543ms1億次獲取。如果Calendar.getInstance() 在方法內聲明,每秒處理速度爲300萬封頂 內存 直接上到600MB 。
如果Calendar.getInstance() 在方法內聲明,內存會根據CPU處理速度 程直線上升 。因爲每一次 調用,getInstance 都會去創建一個對象並非單例 而且 內部會創建一個int數組
在方法外聲明 有一點要注意: 就是每一次都要刷新 當前時間戳 否則 時間 永遠都是 第一次調用getInstance 的時間
轉:https://www.jianshu.com/p/add0123faa45