原来获取Jvm信息如此简单

本文介绍了如何在Java中获取JVM和操作系统的运行信息,包括JVM内存、线程、CPU及系统内存等。通过ManagementFactory获取JVM内存信息,使用oshi库获取OS详细状态,为问题定位提供实用工具。

前言

当线上出现问题的时候,最最最重要的是定位问题。一旦定位到问题了,一切都好办了。但是这个定位问题,需要的不仅仅是理论知识,还需要丰富的实操经验。而丰富的经验从哪里来呢,就是对于工具的运用和数据的分析中来,接下来主要介绍一下java中如何去获取JVM跟os的信息?

下面让我们直接进入主题:

JAVA代码里如何去获取JVM/OS的运行信息呢?

  • Jvm信息使用ManagementFactory去获取
  • OS运行信息推荐使用oshi去获取
<dependency>
            <groupId>com.github.oshi</groupId>
            <artifactId>oshi-core</artifactId>
            <version>5.7.5</version>
</dependency>

获取jvm运行内存信息

格式化内存大小类

package io.github.quickmsg.metric.utils;

import java.text.DecimalFormat;

/**
 * @author coding途中
 */
public class FormatUtils {

    /**
     * 单位转换
     *
     * @param byteNumber number
     * @return desc
     */
   public static String formatByte(long byteNumber) {
        //换算单位
        double FORMAT = 1024.0;
        double kbNumber = byteNumber / FORMAT;
        if (kbNumber < FORMAT) {
            return new DecimalFormat("#.##KB").format(kbNumber);
        }
        double mbNumber = kbNumber / FORMAT;
        if (mbNumber < FORMAT) {
            return new DecimalFormat("#.##MB").format(mbNumber);
        }
        double gbNumber = mbNumber / FORMAT;
        if (gbNumber < FORMAT) {
            return new DecimalFormat("#.##GB").format(gbNumber);
        }
        double tbNumber = gbNumber / FORMAT;
        return new DecimalFormat("#.##TB").format(tbNumber);
    }
}

废话不多说直接上代码:

  • 第一个种方法通过ManagementFactory获取MemoryMXBean
MemoryMXBean mxb = ManagementFactory.getMemoryMXBean();
        //堆
System.out.println("Max:" +FormatUtils.formatByte(mxb.getHeapMemoryUsage().getMax()));    //Max:1776MB
System.out.println("Init:" + FormatUtils.formatByte(mxb.getHeapMemoryUsage().getInit()));  //Init:126MB
System.out.println("Committed:" + FormatUtils.formatByte(mxb.getHeapMemoryUsage().getCommitted()));   //Committed:121MB
System.out.println("Used:" + FormatUtils.formatByte(mxb.getHeapMemoryUsage().getUsed()));  //Used:7MB
System.out.println(mxb.getHeapMemoryUsage().toString());   
        //直接内存
System.out.println("Max:" +FormatUtils.formatByte(mxb.getNonHeapMemoryUsage().getMax()));    //Max:0MB
System.out.println("Init:" + FormatUtils.formatByte(mxb.getNonHeapMemoryUsage().getInit()));  //Init:2MB
System.out.println("Committed:" + FormatUtils.formatByte(mxb.getNonHeapMemoryUsage().getCommitted()));   //Committed:8MB
System.out.println("Used:" + FormatUtils.formatByte(mxb.getNonHeapMemoryUsage().getUsed()));  //Used:7MB
System.out.println(mxb.getNonHeapMemoryUsage().toString()); 
  • 使用Runtime对象去获取
JSONObject cpuInfo = new JSONObject();
Properties props = System.getProperties();
Runtime runtime = Runtime.getRuntime();
long jvmTotalMemoryByte = runtime.totalMemory();
long freeMemoryByte = runtime.freeMemory();
        //jvm总内存
cpuInfo.put("total", FormatUtils.formatByte(jvmTotalMemoryByte));
        //空闲空间
cpuInfo.put("free", FormatUtils.formatByte(freeMemoryByte));
        //jvm最大可申请
cpuInfo.put("max", FormatUtils.formatByte(runtime.maxMemory()));
        //jvm已使用内存
cpuInfo.put("user", FormatUtils.formatByte(jvmTotalMemoryByte - freeMemoryByte));
        //jvm内存使用率
cpuInfo.put("usageRate", new DecimalFormat("#.##%").format((jvmTotalMemoryByte - freeMemoryByte) * 1.0 / jvmTotalMemoryByte));
        //jdk版本
cpuInfo.put("jdkVersion", props.getProperty("java.version"));
        //jdk路径
cpuInfo.put("jdkHome", props.getProperty("java.home"));
        
System.out.println(cpuInfo);

获取jvm运行线程信息

ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
Map<String, Number> map = new LinkedHashMap<String, Number>();
// 线程总数
map.put("jvm.thread.count", threadBean.getThreadCount());
// 守护线程总数
map.put("jvm.thread.daemon.count", threadBean.getDaemonThreadCount());
// 开启线程总数
map.put("jvm.thread.totalstarted.count", threadBean.getTotalStartedThreadCount());
// 获取线程详细信息
ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadBean
### JVM 垃圾回收机制详解 #### 什么是垃圾回收? 垃圾回收(Garbage Collection, GC)是指 Java 虚拟机自动管理内存的过程。它通过识别并释放那些不再被程序使用的对象所占用的内存,从而防止内存泄漏和提高应用程序性能[^1]。 #### 基本原理 JVM 的垃圾回收基于分代假设理论,即大多数对象生命周期较短,只有少数对象会存活较长的时间。因此,JVM 将堆分为年轻代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation 或 Metaspace)。不同代的对象有不同的垃圾回收策略[^1]。 - **年轻代**:主要存储新创建的对象。当对象经过多次 Minor GC 后仍然存活,则会被晋升到老年代。 - **老年代**:用于存放寿命较长的对象。通常只会在 Major GC 或 Full GC 中清理。 - **元空间/Metaspace**:自 JDK 8 开始替代永久代,主要用于存储类的元数据信息。 #### 不同类型的垃圾回收器及其特点 ##### Serial 收集器 这是最基础也是最早的单线程垃圾收集器,适用于客户端模式下的简单应用环境。其优点在于实现简单高效,但由于采用 Stop-The-World (STW) 方式工作,在高并发场景下表现不佳。 ##### Parallel 收集器 也被称为吞吐量优先收集器,它是多线程版本的 Serial 收集器。适合于运行在服务器端的应用场合,能够充分利用 CPU 多核特性来提升整体处理能力。 ##### CMS (Concurrent Mark Sweep) 收集器 CMS 是一种以获取最低延迟为目标的垃圾收集器。它的核心思想是在用户线程与GC线程之间交替执行部分操作,减少暂停时间。然而,CMS 存在一个显著缺点——容易产生浮动垃圾,并且可能会因为未能及时完成而发生“并发失败”的情况[^2]。 ##### G1 (Garbage First) 收收器 作为新一代的垃圾收集器,G1 设计之初就被赋予了取代 CMS 的使命。相比传统分区方式,G1 把整个堆划分为多个大小相等的区域(Region),并通过预测哪些 Region 包含更多可回收的空间来进行优先级排序清扫。这种方式不仅有助于控制停顿时间目标(STTG),还能有效避免因碎片化带来的问题[^2]。 以下是关于如何启用 G1 收集器的一个示例配置命令: ```bash java -XX:+UseG1GC ... ``` 尽管如此,需要注意的是,虽然 G1 提供了一定程度上的可控性,但在某些特定条件下仍可能出现长时间 STW 现象,比如混合阶段过长等问题[^3]。 #### 解决常见 JVM GC 相关问题的方法论 针对具体的业务需求调整合适的参数设置至关重要。例如可以通过监控工具分析当前系统的瓶颈所在,进而决定是否需要增加初始堆大小(-Xms),最大堆大小(-Xmx),或者调节新生代比例(-XX:NewRatio=N)等等[^1]。 同时也要关注日志输出中的关键指标变化趋势,像 Eden Space 使用率、Survivor Ratio 设置合理性等方面都需要仔细考量。此外还可以尝试引入第三方诊断软件如 VisualVM 来辅助定位深层次原因[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值