记一次jvm堆栈分析

记一次jvm堆栈分析threadPoolLock.if (ThreadManager.pool.// if (runnableList.// throw new LocalRuntimeException(“线程集合size:” + runnableList.TimeUnit.r – new Th…

程序如下:

@Slf4j
public abstract class XExecutor implements DataExecutor {
    private final Lock threadPoolLock = new ReentrantLock();
    @Override
    public boolean executor(List<DataRunnable> runnableList, int corePoolSize, int maxPoolSize, int capacity, String threadName) {
        try {
            threadPoolLock.lock();
            if (ThreadManager.pool.get() == null) {
                if (runnableList == null) {
                    throw new LocalRuntimeException("线程集合为空");
                }
// if (runnableList.size() >= capacity) {
// throw new LocalRuntimeException("线程集合size:" + runnableList.size() + " > 线程池队列容量capacity:" + capacity);
// }
                ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize,//核心池大小
                        maxPoolSize,//最大池大小
                        1000,//线程最大空闲时间,超过此空闲时间可以被收回
                        TimeUnit.MILLISECONDS, //最大空闲时间的单位
                        new ArrayBlockingQueue<>(capacity),//用于保存执行任务的队列,可以选择其他不同的队列来做任务管理
                        r -> new Thread(r, threadName + "-" + r.hashCode())
                );
                ThreadManager.pool.set(threadPool);
            }
            CountDownLatch countDownLatch = new CountDownLatch(runnableList.size());
            RunnableStatus runnableStatus = new RunnableStatus(countDownLatch);
            runnableList.forEach(runnable -> {
                runnable.setRunnableStatus(runnableStatus);
                ThreadManager.pool.get().submit(runnable);
            });
            //等待所有线程完毕
            ThreadManager.pool.get().shutdown();
            countDownLatch.await();
            this.remove(threadName);
            log.info("线程池执行完毕:{}", threadName);

            if (!runnableStatus.getExceptionList().isEmpty()) {
                runnableStatus.getExceptionList().forEach(e -> log.error("multi thread err,", e));
                return false;
            }
            return true;
        } catch (Exception e) {
            log.error("处理数据出现错误:", e);
           throw new RuntimeException("线程执行出现问题.....",e);
        } finally {
            threadPoolLock.unlock();
        }
        return false;
    }

使用jstack导出线程堆栈

jstack 16306 > jstack.tdump

使用jmap导出堆内存

jmap -dump:format=b,file=HeapDump.hprof 16306

使用VisualVM

在jdk的bin目录下,打开自带的jvisualVm工具
点击打开按钮
在这里插入图片描述

根据线程堆栈中

使用jvisualVm打开线程堆栈jstack.tdump
在这里插入图片描述
在堆栈中,找到如下信息
在这里插入图片描述
其中tid没有弄清楚是什么,有人说是线程栈的开始地址,貌似有道理。

在内存堆栈中,使用OQL查找对象

select heap.findObject(“0xf3800b58”)
在这里插入图片描述
点击对象连接,可以看到:
在这里插入图片描述
可以看到线程池中的两个执行线程,都在等待这个对象地址的锁

另外:介绍一个查找最消耗cpu的java线程,jps 找到java进程PID

命令:ps -mp p i d ∗ ∗ − o T H R E A D , t i d , t i m e 或 者 p s − L f p ∗ ∗ {pid}** -o THREAD,tid,time 或者 ps -Lfp ** pid∗∗−oTHREAD,tid,time或者ps−Lfp∗∗{pid}

www.cnblogs.com/wangkangluo…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/36677.html

(0)
上一篇 2023-11-17
下一篇 2023-11-17

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注