Skip to content

Instantly share code, notes, and snippets.

@sunwu51
Created March 28, 2022 09:19
Show Gist options
  • Save sunwu51/f09be75022418dec62ad903fe6baf7a5 to your computer and use it in GitHub Desktop.
Save sunwu51/f09be75022418dec62ad903fe6baf7a5 to your computer and use it in GitHub Desktop.
print java object header
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class ObjectHeaderUtil {
private static Unsafe getUnsafe() throws Exception {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
Field field = unsafeClass.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
}
private static void printLockHeader(Object obj) throws Exception {
Unsafe us = getUnsafe();
StringBuilder sb = new StringBuilder();
int status = us.getByte(obj, 0L) & 0B11;
// 0 轻量级 1 无锁或偏向 2 重量级 3 GC标记
switch (status){
case 0:
// ptr_to_lock_record:62|lock:2
long ptrToLockRecord =
(byteMod(us.getByte(obj, 0L))>>2) +
(byteMod(us.getByte(obj, 1L))<<6) +
(byteMod(us.getByte(obj, 2L))<<14) +
(byteMod(us.getByte(obj, 3L))<<22) +
(byteMod(us.getByte(obj, 4L))<<30) +
(byteMod(us.getByte(obj, 5L))<<38) +
(byteMod(us.getByte(obj, 6L))<<46) +
(byteMod(us.getByte(obj, 7L))<<54);
sb.append("锁状态:轻量级锁,LockRecord地址:")
.append(Long.toHexString(ptrToLockRecord))
;
break;
case 1:
boolean biased = (us.getByte(obj, 0L)&4) == 4;
if(!biased){
// unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2
int hashCode = (int)(byteMod(us.getByte(obj, 1L))
+ (byteMod(us.getByte(obj, 2L))<<8)
+ (byteMod(us.getByte(obj, 3L))<<16)
+ ((byteMod(us.getByte(obj, 4L))&Integer.MAX_VALUE) <<24))
;
int age = (us.getByte(obj,0L)>>3)&0B1111;
sb.append("锁状态:无锁,hashCode:")
.append(hashCode)
.append(",age: ")
.append(age);
}else{
//thread:54|epoch:2|unused:1| age:4 | biased_lock:1 | lock:2
long thread = (byteMod(us.getByte(obj, 1L))>>2) +
(byteMod(us.getByte(obj, 2L))<<6) +
(byteMod(us.getByte(obj, 3L))<<14) +
(byteMod(us.getByte(obj, 4L))<<22) +
(byteMod(us.getByte(obj, 5L))<<30) +
(byteMod(us.getByte(obj, 6L))<<38) +
(byteMod(us.getByte(obj, 7L))<<46);
;
int epoch = us.getByte(obj, 1L) & 0B11;
int age = (us.getByte(obj,0L)>>3)&0B1111;
sb.append("锁状态:偏向锁,thread:")
.append(thread)
.append(",epoch: ")
.append(epoch)
.append(",age: ")
.append(age);
}
break;
case 2:
// ptr_to_heavyweight_monitor:62| lock:2
long ptrToMonitor =
(byteMod(us.getByte(obj, 0L))>>2) +
(byteMod(us.getByte(obj, 1L))<<6) +
(byteMod(us.getByte(obj, 2L))<<14) +
(byteMod(us.getByte(obj, 3L))<<22) +
(byteMod(us.getByte(obj, 4L))<<30) +
(byteMod(us.getByte(obj, 5L))<<38) +
(byteMod(us.getByte(obj, 6L))<<46) +
(byteMod(us.getByte(obj, 7L))<<54);
sb.append("锁状态:重量级锁,Monitor地址:")
.append(Long.toHexString(ptrToMonitor))
;
break;
case 3:
sb.append("锁状态:GC标记");
break;
default:
break;
}
if(obj instanceof Object[]){
int arrLen = us.getInt(obj, 3L);
sb.append("对象为数组类型,数组长度:")
.append(arrLen);
}
sb.append("\n").append("---------------").append("\n");
System.out.println(sb.toString());
}
private static long byteMod(byte b){
if(b>=0){
return b;
}
return b + 256;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment