格式化Java内存工具JOL输出

简介: 格式化Java内存工具JOL输出
import org.openjdk.jol.info.ClassLayout;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PrintObjectHeader {
    /**
     * Get binary data
     *
     * @param o
     * @return
     */
    public static String getObjectHeader(Object o) {
        ByteOrder order = ByteOrder.nativeOrder();//Byte order
        String table = ClassLayout.parseInstance(o).toPrintable();
        Pattern p = Pattern.compile("(0|1){8}");
        Matcher matcher = p.matcher(table);
        List<String> header = new ArrayList<String>();
        while (matcher.find()) {
            header.add(matcher.group());
        }
        //Little-endian machines, need to traverse in reverse
        StringBuilder sb = new StringBuilder();
        if (order.equals(ByteOrder.LITTLE_ENDIAN)) {
            Collections.reverse(header);
        }
        for (String s : header) {
            sb.append(s).append(" ");
        }
        return sb.toString().trim();
    }
    /**
     * Parsing object header function for 64bit jvm
     * In 64bit jvm, the object header has two parts: Mark Word and Class Pointer, Mark Word takes 8 bytes, Class Pointer takes 4 bytes
     *
     * @param s Binary string of object header (each 8 bits, separated by a space)
     */
    public static void parseObjectHeader(String s) {
        String[] tmp = s.split(" ");
        System.out.print("Class Pointer: ");
        for (int i = 0; i < 4; ++i) {
            System.out.print(tmp[i] + " ");
        }
        System.out.println("\nMark Word:");
        if (tmp[11].charAt(5) == '0' && tmp[11].substring(6).equals("01")) {//0 01 lock-free state, regardless of GC mark
            //notice: Mark word structure without lock: unused(25bit) + hashcode(31bit) + unused(1bit) + age(4bit) + biased_lock_flag(1bit) + lock_type(2bit)
            // The reason why hashcode only needs 31bit is: hashcode can only be greater than or equal to 0, eliminating the negative range, so you can use 31bit to store
            System.out.print("\thashcode (31bit): ");
            System.out.print(tmp[7].substring(1) + " ");
            for (int i = 8; i < 11; ++i) System.out.print(tmp[i] + " ");
            System.out.println();
        } else if (tmp[11].charAt(5) == '1' && tmp[11].substring(6).equals("01")) {//1 01, which is the case of biased lock
            //notice: The object is in a biased lock, its structure is: ThreadID(54bit) + epoch(2bit) + unused(1bit) + age(4bit) + biased_lock_flag(1bit) + lock_type(2bit)
            // ThreadID here is the thread ID holding the biased lock, epoch: a timestamp of the biased lock, used for optimization of the biased lock
            System.out.print("\tThreadID(54bit): ");
            for (int i = 4; i < 10; ++i) System.out.print(tmp[i] + " ");
            System.out.println(tmp[10].substring(0, 6));
            System.out.println("\tepoch: " + tmp[10].substring(6));
        } else {//In the case of lightweight locks or heavyweight locks, regardless of the GC mark
            //notice: JavaThread*(62bit,include zero padding) + lock_type(2bit)
            // At this point, JavaThread* points to the monitor of the lock record/heavyweight lock in the stack
            System.out.print("\tjavaThread*(62bit,include zero padding): ");
            for (int i = 4; i < 11; ++i) System.out.print(tmp[i] + " ");
            System.out.println(tmp[11].substring(0, 6));
            System.out.println("\tLockFlag (2bit): " + tmp[11].substring(6));
            System.out.println();
            return;
        }
        System.out.println("\tage (4bit): " + tmp[11].substring(1, 5));
        System.out.println("\tbiasedLockFlag (1bit): " + tmp[11].charAt(5));
        System.out.println("\tLockFlag (2bit): " + tmp[11].substring(6));
        System.out.println();
    }
    public static void printObjectHeader(Object o) {
        if (o == null) {
            System.out.println("null object.");
            return;
        }
        parseObjectHeader(getObjectHeader(o));
    }
}
相关文章
|
10天前
|
存储 Java 程序员
Java中对象几种类型的内存分配(JVM对象储存机制)
Java中对象几种类型的内存分配(JVM对象储存机制)
43 5
Java中对象几种类型的内存分配(JVM对象储存机制)
|
23小时前
|
Java
在Java编程的广阔天地中,条件语句是控制程序流程、实现逻辑判断的重要工具。
在Java编程中,if-else与switch作为核心条件语句,各具特色。if-else以其高度灵活性,适用于复杂逻辑判断,支持多种条件组合;而switch在多分支选择上表现优异,尤其适合处理枚举类型或固定选项集,通过内部跳转表提高执行效率。两者各有千秋:if-else擅长复杂逻辑,switch则在多分支选择中更胜一筹。理解它们的特点并在合适场景下使用,能够编写出更高效、易读的Java代码。
5 1
|
4天前
|
存储 Java 开发者
Java 内存模型与垃圾回收机制的深度剖析
在Java的世界里,理解其内存模型和垃圾回收机制是提升编程效率的关键。本文将通过浅显易懂的语言,带你深入了解Java的内存分配原理和垃圾回收过程,让你对Java的性能调优有更深刻的认识。
|
7天前
|
安全 Java 程序员
深入浅出Java内存模型:探索JMM的奥秘
在Java编程世界中,理解其内存模型(JMM)是提升代码性能和确保线程安全的关键。本文将带你走进Java内存模型的大门,通过浅显易懂的方式揭示其工作原理,并指导你如何在实际开发中有效利用JMM来避免常见的并发问题。
|
9天前
|
Java 开发者
深入浅出Java内存管理
在Java的世界里,内存管理是支撑程序运行的基石。本文将通过浅显易懂的语言和生动的比喻,带你了解Java是如何巧妙地处理内存分配与回收的。我们将一起探索对象在Java内存模型中的生命周期,以及JVM如何通过垃圾收集机制保持内存的健康状态。无论你是初学者还是有一定经验的开发者,这篇文章都将为你揭开Java内存管理的神秘面纱。
|
3天前
|
存储 监控 算法
掌握Java内存管理:从入门到精通
在Java的世界里,内存管理是程序运行的心脏。本文将带你走进Java内存管理的奥秘,从基础概念到高级技巧,一步步揭示如何优化你的Java应用。准备好迎接挑战,让我们共同揭开高效内存使用的面纱!
|
6天前
|
存储 缓存 安全
Java内存模型详解
该文章主要介绍了Java内存模型的相关概念和技术细节,包括Java内存模型的定义、缓存一致性策略、内存交互操作、内存屏障等。
|
7天前
|
监控 Java
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
14 0
|
8天前
|
安全 Java 程序员
深入浅出Java内存模型
Java内存模型(JMM)是Java并发编程的基石,它定义了线程如何通信以及如何同步。本文将通过通俗易懂的语言和生动的比喻,带领读者一步步揭开JMM的神秘面纱,理解其工作原理及对程序设计的影响。
|
10天前
|
算法 Java 开发者
Java 内存管理:垃圾收集器的奥秘
在Java的世界里,有一个默默无闻的英雄——垃圾收集器。它负责回收不再使用的对象,保证程序的高效运行。但你知道它是如何工作的吗?本文将带你深入了解垃圾收集器的内部机制,让你对这个幕后英雄有更深的认识。
17 0