(jstack+内存泄露深度解析):从线程堆栈看透系统性能瓶颈

第一章:jstack 分析内存泄露的线程状态

在 Java 应用运行过程中,内存泄露往往伴随着异常的线程行为。虽然 jstack 主要用于分析线程堆栈信息,但结合线程状态与堆栈快照,可以有效识别导致内存泄露的可疑线程。

获取线程堆栈快照

使用 jstack 命令可输出指定 Java 进程的线程堆栈信息。执行以下指令:

# 获取进程 ID
jps -l

# 输出线程堆栈到文件
jstack <pid> > thread_dump.log
该命令将目标 JVM 进程的所有线程状态和调用栈输出至日志文件,便于后续分析。

识别可疑线程状态

线程处于以下状态时可能与内存泄露相关:
  • WAITING 或 TIMED_WAITING:长时间等待且持有对象引用,可能导致对象无法被回收
  • BLOCKED:线程阻塞在锁竞争,可能引发请求堆积,间接导致内存增长
  • RUNNABLE:执行任务中持续创建对象而未释放,是内存泄露的常见源头

分析线程堆栈中的模式

查看 thread_dump.log 中重复出现的调用栈,尤其是涉及自定义业务类或线程池的任务提交。例如:

"Thread-5" #15 prio=5 os_prio=0 tid=0x00007f8a8c0b6000 nid=0x7b0e waiting on condition [0x00007f8a5d4d5000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
若多个线程长期停留在相同位置,且应用内存持续上升,则需检查任务逻辑是否持有外部引用,如静态集合、缓存未清理等。

线程状态与内存行为关联对照表

线程状态潜在风险建议操作
RUNNABLE持续分配对象,未释放引用检查循环或异步任务中的对象生命周期
WAITING持有锁或引用导致对象无法回收分析 wait() 前的调用栈,定位引用链
BLOCKED锁竞争引发请求积压优化同步范围,避免长事务

第二章:jstack 工具核心原理与线程状态解析

2.1 Java 线程模型与操作系统线程映射

Java 的线程模型依赖于底层操作系统的线程实现,通常采用“一对一”映射方式,即每个 Java 线程对应一个操作系统原生线程。这种模型使得 Java 线程调度由操作系统直接管理,具备良好的并发性能和响应能力。
线程映射机制
在主流 JVM 实现中(如 HotSpot),Java 线程通过线程库(如 pthread)绑定到内核级线程。这意味着线程的创建、调度和销毁均由操作系统负责。

Thread thread = new Thread(() -> {
    System.out.println("运行在线程: " + Thread.currentThread().getName());
});
thread.start(); // JVM 请求 OS 创建本地线程
上述代码调用 start() 后,JVM 会通过 JNI 调用本地方法,最终触发操作系统创建对应的 native thread。该过程涉及内存分配、栈空间设置及上下文初始化。
映射对比表
特性Java 线程操作系统线程
调度权由 OS 掌控自主调度
资源开销较高(因映射)高

2.2 jstack 输出结构深度解读

jstack 生成的线程转储文件包含JVM中所有线程的调用栈信息,其结构清晰且层次分明。每个线程块以线程名、线程ID、优先级和线程状态开头,随后是完整的调用栈。
线程基本信息解析
每条线程信息起始行为:
"main" #1 prio=5 os_prio=0 tid=0x00007f8a8c00a000 nid=0x1b2c runnable [0x00007f8a91d5b000]
其中,tid为线程ID,nid为本地线程ID(十六进制),runnable表示线程状态,方括号内为栈内存地址范围。
调用栈与锁信息
后续行展示从顶层到底层的方法调用链:
   java.lang.Thread.State: RUNNABLE
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:326)
        at java.io.PrintStream.write(PrintStream.java:480)
        - locked <0x000000076ab02ef8> (a java.io.FileOutputStream)
- locked 表示该线程已持有某对象监视器,可用于分析死锁或竞争瓶颈。
  • 线程状态包括:RUNNABLE、BLOCKED、WAITING、TIMED_WAITING
  • BLOCKED 状态通常伴随等待进入 synchronized 块的信息
  • WAITING 线程会标明等待的具体方法,如 Object.wait()

2.3 常见线程状态(RUNNABLE、BLOCKED、WAITING)与性能关联

线程的运行状态直接影响应用的并发能力与响应性能。处于 RUNNABLE 状态的线程正在CPU上执行或等待调度,是高效处理任务的关键。
阻塞与等待状态的影响
当线程进入 BLOCKED(等待锁)或 WAITING(等待通知)状态时,无法推进任务,导致CPU空转或资源闲置。
  • RUNNABLE:高占比通常表示有效计算,但若持续满载可能引发上下文切换开销;
  • BLOCKED:频繁出现常因锁竞争激烈,如 synchronized 争用;
  • WAITING:合理使用可协调资源,但长时间等待可能暴露协作逻辑瓶颈。

synchronized void criticalSection() {
    // 线程在此块内为 RUNNABLE
    // 其他尝试进入的线程将变为 BLOCKED
    sharedResource.access();
}
上述代码中,对共享资源的同步访问可能导致多个线程在锁上阻塞,增加 BLOCKED 状态线程数,进而降低整体吞吐量。优化建议包括使用更细粒度锁或 java.util.concurrent 工具类。

2.4 使用 jstack 定位高 CPU 占用线程实战

在生产环境中,Java 应用出现 CPU 使用率过高时,可通过 jstack 工具快速定位问题线程。首先使用 top -Hp <pid> 查看占用 CPU 最高的线程 ID(TID),再将其转换为 16 进制。
获取线程堆栈信息
执行以下命令导出当前 JVM 线程快照:
jstack <java_pid> > thread_dump.txt
该命令将指定 Java 进程的所有线程堆栈输出到文件中,便于后续分析。
定位高耗时线程
在 thread_dump.txt 中搜索 16 进制的 TID,找到对应线程的堆栈信息。例如:
"http-nio-8080-exec-5" #15 daemon prio=5 os_prio=0 tid=0x00007f8c8c0b8000 nid=0xabc runnable ...
其中 nid=0xabc 为线程 native ID,若其状态为 runnable 且持续占用 CPU,说明该线程可能执行了死循环或复杂计算。 结合堆栈中的类名与方法名,可精准定位代码瓶颈点,进而优化逻辑或修复异常行为。

2.5 线程转储获取时机与多维度采样策略

在高并发系统中,线程状态的瞬时快照对性能诊断至关重要。合理选择线程转储(Thread Dump)的触发时机,可精准定位阻塞、死锁或资源竞争问题。
典型触发场景
  • 应用响应延迟突增,CPU使用率持续高位
  • 手动触发以分析特定业务高峰期的线程行为
  • 通过监控系统检测到线程池任务积压
多维度采样策略
为避免单次采样偏差,建议采用周期性多轮采样。例如每隔10秒采集一次,连续获取5次转储文件,用于对比线程状态演变。
jstack -l 12345 > threaddump_$(date +%s).log
该命令通过 jstack 获取进程ID为12345的JVM线程转储,-l 参数输出锁信息,有助于识别死锁和等待链。
自动化采样流程
定时任务 → 条件判断(CPU/响应时间)→ 连续采样 → 文件归档 → 分析告警

第三章:内存泄露的线程行为特征分析

3.1 内存泄露典型场景中的线程活动模式

在多线程应用中,内存泄露常伴随异常的线程活动模式出现。典型的场景包括线程未正确终止、线程局部存储(Thread Local)滥用以及任务队列堆积。
线程未释放资源
当工作线程执行完成后未显式关闭或未释放绑定的上下文对象,会导致关联对象无法被垃圾回收。

public class Task implements Runnable {
    private final LargeObject context; // 长生命周期持有大对象

    public Task(LargeObject ctx) {
        this.context = ctx;
    }

    public void run() {
        // 执行任务,context 始终可达
    }
}
上述代码中,若线程池中的线程长期持有 context 引用且无清理机制,LargeObject 将持续驻留内存。
常见泄露模式对比
模式线程行为泄露根源
守护线程残留线程未中断循环引用 Runnable
ThreadLocal 泄露未调用 remove()Entry 弱引用失效

3.2 长生命周期线程与对象持有链关系剖析

在多线程编程中,长生命周期线程常驻内存,若其持有对短期对象的引用,易形成对象持有链,导致本应被回收的对象无法释放。
典型的持有链场景
  • 线程通过 Runnable 持有外部类实例
  • 任务队列中缓存了带有上下文的对象引用
  • 监听器或回调接口未及时解绑
代码示例:隐式引用导致内存泄漏

public class LongLivedTask implements Runnable {
    private final LargeObject payload; // 长期持有大对象

    public LongLivedTask(LargeObject payload) {
        this.payload = payload;
    }

    @Override
    public void run() {
        // payload 在任务执行完毕后仍被持有
        process(payload);
    }
}
上述代码中,即便 payload 业务生命周期已结束,但由于线程池中的线程长期存活,该引用将持续存在,阻碍垃圾回收。
持有链影响对比
持有方式回收时机风险等级
强引用持有线程终止高
弱引用/软引用GC 触发时低

3.3 结合堆直方图识别异常线程驱动的内存增长

在排查JVM内存持续增长问题时,若常规堆转储难以定位根源,可结合堆直方图与线程活动分析。通过定期采样堆直方图,观察特定对象类型的数量变化趋势,有助于发现潜在的内存泄漏。
关键命令与输出解析

jmap -histo:live <pid> | head -20
该命令输出活跃对象的实例数与占用内存排名。若发现某类对象(如`java.util.HashMap$Node`)数量随时间显著上升,需进一步关联线程栈信息。
线程与对象增长关联分析
  • 使用jstack <pid>获取线程快照,重点观察RUNNABLE状态的线程
  • 比对高频创建对象的分配栈是否集中于某一工作线程
  • 确认是否存在任务队列积压或回调未释放导致的对象滞留
当发现某后台任务线程频繁提交闭包导致外部引用被长期持有,即可判定为线程驱动型内存增长。

第四章:基于线程堆栈的内存泄露诊断实践

4.1 案例驱动:Web 应用中线程局部变量引发的内存累积

在高并发 Web 应用中,开发者常误用线程局部变量(ThreadLocal)存储用户上下文,导致内存累积问题。
问题场景还原
以下代码展示了典型的内存泄漏模式:

public class UserContext {
    private static final ThreadLocal<String> userId = new ThreadLocal<>();

    public static void setUser(String id) {
        userId.set(id);
    }

    public static String getUser() {
        return userId.get();
    }
}
每次请求调用 setUser() 会将当前用户 ID 绑定到线程,但未调用 remove() 清理。在使用线程池的场景下,线程长期存活,导致 ThreadLocal 持有的对象无法被回收。
解决方案与最佳实践
  • 在请求结束时显式调用 ThreadLocal.remove()
  • 结合过滤器统一管理生命周期,确保资源释放
  • 避免在线程池任务中长期持有大对象引用

4.2 定时任务线程池未关闭导致的资源滞留分析

在Java应用中,定时任务常通过`ScheduledExecutorService`实现。若任务执行完毕后未显式调用`shutdown()`,线程池将保持运行状态,导致JVM无法正常退出。
典型问题代码示例

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(() -> {
    System.out.println("执行数据同步");
}, 0, 5, TimeUnit.SECONDS);
// 缺少 scheduler.shutdown()
上述代码创建了周期性任务但未关闭线程池,致使线程持续驻留,消耗内存与CPU调度资源。
资源泄漏影响
  • 线程对象无法被GC回收,引发内存泄漏
  • 活跃线程阻止JVM进程终止
  • 在容器化部署中可能导致节点资源耗尽
解决方案建议
应在应用关闭钩子或上下文销毁时调用:

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    scheduler.shutdown();
    try {
        if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
            scheduler.shutdownNow();
        }
    } catch (InterruptedException e) {
        scheduler.shutdownNow();
        Thread.currentThread().interrupt();
    }
}));
该机制确保JVM收到终止信号时能优雅关闭线程池,释放底层资源。

4.3 Native 线程与 JNI 调用中的隐式内存泄漏排查

在 Android 或 JNI 开发中,Native 线程频繁调用 Java 方法时,若未正确管理局部引用(Local Reference),极易引发隐式内存泄漏。JVM 每次通过 env->CallXXXMethod 创建的局部引用不会自动释放,累积过多将导致 native heap 内存耗尽。
常见泄漏场景
  • 在 native 线程循环中调用 FindClass,重复生成未释放的类引用
  • 未在适当作用域调用 PushLocalFrame / PopLocalFrame
  • 误将局部引用跨线程存储为全局变量而未转换
安全调用示例

for (;;) {
    if (env->PushLocalFrame(16) != JNI_OK) continue;
    jclass clazz = env->FindClass("java/lang/String");
    // 使用 clazz...
    env->PopLocalFrame(nullptr); // 自动释放所有局部引用
}
上述代码通过 PushLocalFrame 显式创建引用帧,PopLocalFrame 一次性回收,避免引用堆积。建议在长生命周期 native 线程中,对高频 JNI 调用使用该机制。

4.4 综合运用 jstack、jmap 与 MAT 完成根因定位

在排查复杂生产环境中的 JVM 问题时,单一工具往往难以定位根本原因。通过组合使用 jstack、jmap 和 MAT(Memory Analyzer Tool),可实现线程状态与内存对象的联合分析。
诊断流程概览
  • 使用 jstack 获取线程快照,识别是否存在死锁或长时间阻塞
  • 通过 jmap 生成堆转储文件:
    jmap -dump:format=b,file=heap.hprof <pid>
    该命令导出指定进程的完整堆内存,用于后续深入分析
  • 将 heap.hprof 文件导入 MAT,利用其“Leak Suspects”报告快速定位潜在内存泄漏点
MAT 中的关键分析视角
视图用途
Dominator Tree识别主导对象及其保留堆大小
Thread Overview关联线程栈与内存分配,发现线程持有的大对象
结合线程栈与内存分布,可精准判断是并发控制不当还是对象生命周期管理失误导致系统性能劣化。

第五章:从线程视角构建系统性能治理闭环

在高并发系统中,线程是资源调度的基本单位,也是性能瓶颈的常见源头。通过监控线程状态、分析线程堆栈及优化线程池配置,可实现从问题发现到根因定位的闭环治理。
线程堆栈分析实战
当系统出现响应延迟时,可通过 jstack 获取 JVM 线程快照。例如:

jstack 12345 > thread_dump.log
分析日志中处于 BLOCKED 或 WAITING 状态的线程,常能定位锁竞争热点。某电商系统在大促期间频繁超时,经堆栈分析发现大量线程阻塞在库存扣减方法上,最终通过引入分段锁将吞吐量提升 3 倍。
线程池配置调优策略
合理配置线程池是避免资源耗尽的关键。以下为不同场景下的推荐配置:
场景核心线程数队列类型拒绝策略
CPU 密集型CPU 核心数SynchronousQueueCallerRunsPolicy
IO 密集型2 × CPU 核心数LinkedBlockingQueueAbortPolicy
基于指标的动态治理
整合 Prometheus 与 Grafana 可实现线程指标可视化。关键监控项包括:
  • 活跃线程数(Active Count)
  • 任务等待时间
  • 线程池饱和度
  • 拒绝任务数
[监控] → [告警触发] → [自动扩容线程池] → [流量降级] → [反馈至APM]
某金融网关通过该闭环机制,在交易峰值期间自动调整线程池容量,并结合熔断策略保障核心链路稳定。
MPP的jstack分析结果 立即下载

相关推荐

HFSS实战:手把手教你设计3.3-10.6GHz超宽带微带天线(附S11优化技巧)

本文提供了一份基于Ansys HFSS的超宽带微带天线实战设计指南,详细讲解了从3.3GHz到10.6GHz天线的建模、仿真与优化全流程。文章重点剖析了阻抗匹配的核心挑战,并分享了通过接地板开槽、参数化扫描及目标驱动优化等系统性技巧来优化S11曲线的实用方法,帮助射频工程师快速掌握超宽带天线设计的关键技能。

2y3u4i5o6p的博客 1081

Jstack查询线程堆栈

Jstack是什么? jstack是java虚拟机自带的一种堆栈跟踪工具。 jstack主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁)。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工

weixin_37862824的博客 1万+

【Konva】解决图形加入group后无法获取到绝对坐标,以及group内绘制新图形坐标偏移的问题

解决konva绘图开发时“图形加入group后坐标不会变动,无法获取到绝对坐标”的问题

近10年前端开发工作经验,为你分享日常经验所得 1499

Java程序:jstack

如果有一天,你的Java程序长时间停顿,也许是它病了,需要用jstack拍个片子分析分析,才能诊断具体什么病症,是死锁综合征,还是死循环等其他病症,本文我们一起来学习jstack命令~jstack 的功能jstack用法线程状态等基础回顾实战案例1:jstack 分析死锁实战案例2:jstack 分析CPU 过高jstack用于生成线程快照的,我们分析线程的情况,需要复习一下线程状态吧,拿小凳子坐好,复习一下啦~New:创建后尚未启动的线程处于这种状态,不会出现在Dump中。

z_ssyy的博客 5111

Dify使用教程(创建应用)

Dify的安装部署我已经写过了,简单的模型配置我也在前面进行了讲解,今天我们主要来讲讲如何使用Dify。

wal1314520的博客 1万+

Ubuntu图形界面崩溃?从tty到GUI的终极修复指南

本文提供了Ubuntu图形界面崩溃后进入tty的终极修复指南。详细介绍了如何诊断显示管理器(如LightDM或GDM3)状态,并通过重装、切换显示管理器、修复依赖、系统升级及排查显卡驱动等核心方案,逐步恢复GUI。帮助用户从命令行界面高效修复桌面环境,避免数据丢失。

vulkan6gpu的博客 778

012-JDK可视化监控工具-jstack

一、概述   jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或corefile或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式: jstack [-l] pid      主要分为两个功能:     a. 针对活着的进程做...

dilv4062的博客 617

PowerDesigner16.5下载和安装教程

一、软件下载 1.下载地址(不用复制,直接点击下载链接即可):链接:https://pan.baidu.com/s/1MSnWHWt3SO2Uz5dt9AANAg提取码:z9kk 二、软件安装 1.下载安装包(包含安装文件、汉化包、注册文件) 2.下载后文件内容如下 3....

cicong2374的博客 10万+

jstack命令解析

前言 如果有一天,你的Java程序长时间停顿,也许是它病了,需要用jstack拍个片子分析分析,才能诊断具体什么病症,是死锁综合征,还是死循环等其他病症,本文我们一起来学习jstack命令~ jstack 的功能 jstack用法 线程状态等基础回顾 实战案例1:jstack 分析死锁 实战案例2:jstack 分析CPU 过高 jstack 的功能 jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息. j

fighting_DW 6万+

【WRFDA教程】客观分析(OBSGRID)详解

客观分析(OBSGRID)详解

WW、forever的博客 1133

2026爬虫反爬终极对抗:AST解混淆+算法还原+Python复现全流程实战

本文分享了破解JS加密参数的完整流程,重点介绍AST解混淆和算法还原方法。针对电商网站常见的混淆手段(变量名混淆、控制流平坦化、字符串加密等),作者提出一套高效解决方案:通过AST解析还原可读代码,结合Chrome断点调试定位加密函数,最后用Python精准复现加密逻辑。文章包含具体的代码实现,如字符串数组还原的AST操作示例,并详细说明了从样本采集到验证测试的全流程。该方法已成功应用于10多个网站,将破解时间从一周缩短至一天,为处理JS加密参数提供了可复用的技术方案。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1524

【Java内存泄露排查终极指南】:手把手教你用jstack定位顽固内存问题

快速定位Java内存泄露难题,本文深入讲解Java内存泄露的jstack分析方法,适用于生产环境线程阻塞、堆内存持续增长等场景。通过真实案例解析线程栈追踪与dump文件分析技巧,帮助开发者高效诊断根源问题,提升系统稳定性,值得收藏。

ProceNest的博客 755

Claude Code Skills 入门:内置技能与自定义技能开发

│ Skill 的特点 │1. 封装性:把复杂操作封装成简单命令2. 可复用:一次定义,随处使用3. 可定制:支持参数传入4. 可发现:通过 /skill-name 方式调用打个比方,如果说 Claude Code 的基础工具是「原材料」,那 Skills 就是「预制菜」——只需要简单加热(调用),就能得到成品(结果)。你可以创建自己的 Skill 来封装常用操作。Skill 支持参数,通过。

gaoxiang_120的专栏 671

(jstack+内存泄露深度剖析) 生产环境问题排查的终极武器

快速定位Java应用内存泄露问题,jstack分析内存泄露的线程状态是关键手段。适用于生产环境线程阻塞、堆内存持续增长等场景,通过线程栈追踪定位异常线程,结合GC日志精准诊断。高效、无需重启,值得收藏。

LogicPlex的博客 319

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

仅限内部分享:资深架构师私藏的jstack分析内存泄露秘技(限时公开)

掌握jstack分析内存泄露的线程状态技巧,快速定位Java应用性能瓶颈。适用于高并发场景下排查线程阻塞、死锁等问题,结合实战案例解析dump文件分析方法,精准识别泄露根源。方法实用高效,值得收藏。

LogicWander的博客 267

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java八股文极速版

时间和空间的权衡 值越高空间开销小但是增加了查找开销服务于从Key映射到index的Hash算法,在性能和内存的使用上取平衡,实现一个尽量均匀分布的Hash函数,选取16,是通过位运算的方法进行求取的。线程安全:当多线程执行同一段程序的时候,如果发生了和预期结果不一致的情况,就是线程不安全的,如果和预期结果一致就是线程安全的,可以加锁解决(把并行运行的线程变成串行化执行)。1.加锁 利用Synchronized或者ReenTrantLock来对不安全对象进行加锁。

PassionAnytime的博客 382

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

JVM相关知识

jvm相关知识

xgq_111的博客 510

jstack定位线程堆栈信息【案例汇总】

1.CPU利用率过高,代码定位 找到CPU利用率持续比较高的进程, 命令:top 找到CPU使用率较高的线程ID(TID): 命令:ps p 16480 -L -o pcpu,pid,tid,time,tname,cmd 此处为:16498 将获取的线程号(十进制数)转换成十六进制 printf "%x\n" 16498 结果:4072 结合进程号和线程号,利用jstack查到异常代码所在行 jstack -l <pid> | grep <thr...

MayMatrix 的博客 4945

JVM故障分析及性能优化系列之一:使用jstack定位线程堆栈信息

转载 来源:爪哇堂 原文:https://www.javatang.com/archives/2017/10/19/33151873.html 作者: 前一段时间上线的系统升级之后,出现了严重的高CPU的问题,于是开始了一系列的优化处理之中,现在将这个过程做成一个系列的文章。 基本概念 {#basic-info} 在对Java内存泄漏进行分析的时候,需要对jvm运行期间的内存占用、线程执行等情况进...

a704397849的博客 453

37 jstack 的输出结果分析

前言 之前看到过这样的几篇帖子,dump 中 waiting on condition、parking to wait for 应该怎么理解 是关于 jstack 的日志信息 测试用例 package com.hx.test07; import com.hx.test04.Test18DoubleCheckSingleton; import sun.misc.Unsafe; import java.util.concurrent.locks.LockSupport; /** ...

970655147的专栏 1850

《JVM调优》- Jstack指令详解

jstack命令用于打印指定Java进程、核心文件或远程调试服务器的Java线程堆栈的跟踪信息。查看线程间死锁分析CPU过高原因针对这两个场景,后续会有实战案例~

韩猿外的博客 2783

jstack 堆栈日志分析

一、线程的状态 线程间的状态转换: 1.新建(new):新创建了一个线程对象。 2.可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。 3.运行(running):可运行状态(runnable)的线程获得了cpu 时间片(ti...

675

【JVM实践】(1)jstack分析与实战

jstack是JDK自带的线程堆栈分析工具,用于生成Java虚拟机当前时刻的线程快照(thread dump)。死锁分析线程阻塞CPU占用过高程序响应缓慢。

因为热爱,所以付出 1217

通过jstack日志分析和问题排查

转自:http://www.ccblog.cn/84.htm 前段事件公司出现了一个严重故障(调用dubbo服务一直处于超时,整个服务系统发生雪崩,系统彻底访问不了),一开始怎么都找不到问题的根源,日志的表现形式是dubbo线程池用完了,那么具体是什么导致的没有找到,后然通过jstack日志分析才找到问题的根源,根源就是系统日志代码写有问题。通过这个故障我们来了解下如何通过jstack日志分

张小平的博客 3万+

JAVA进阶5 性能分析工具——JStack

当线程获得了 Monitor,进入了临界区之后,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被 synchronized 的对象)的 wait() 方法,放弃了 Monitor,进入 “Wait Set”队列。但是,要注意的是,因为 Lock类只是一个普通类, JVM无从得知 Lock对象的占用情况,所以在线程 DUMP中,也不会包含关于 Lock的信息, 关于死锁等问题,就不如用 synchronized的编程方式容易识别。比如,在程序中,有多个服务线程,设计成从一个队列里面读取请求数据。

猿来这样-谢厂节的博客 3557
上一篇: flatMap空集合处理的艺术:3个实战案例教你写出健壮的Java流代码
下一篇: connectTimeout配置避坑指南,Java 11 HttpClient稳定性提升的关键一步
FastSolve
博客等级 码龄1年 155粉丝 2011原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值