你如何在Java中获取线程堆栈

你如何在Java中获取线程堆栈,第1张

itjobJava老师讲过:1)线程堆栈概述及基础知识

2)线程堆栈的生成原理以及相关工具

3)不同JVM线程堆栈的格式的差异(SunHotSpot、IBMJRE、OracalJRockit)

4)线程堆栈日志介绍以及解析方法

5)线程堆栈的分析和相关的技术

6)常见的问题模板(线程竟态、死锁、IO调用挂死、垃圾回收/问题、死循环等)

7)线程堆栈问题实例分析

我希望这一系列的培训能给你带来确实的帮助,所以请持续关注每周的文章更新。

但是如果我在学习过程中有疑问或者无法理解文章中的内容该怎么办?

不用担心,把我当做你的导师就好。任何关于线程堆栈的问题都可以咨询我(前提是问题不能太low)。请随意选择下面的几种方式与我取得联系:

1)直接本文下面发表评论(不好意思的话可以匿名)

2)将你的线程堆栈数据提交到RootCauseAnalysisforum

3)发Email给我,地址是@@hotmail

能帮我分析我们产品上遇到的问题么?

当然可以,如果你愿意的话可以把你的堆栈现场数据通过邮件或论坛RootCauseAnalysisforum发给我。处理实际问题是才是学习提升技能的王道。

我真心期望大家能够喜欢这个培训。所以我会尽我所能去为你提供高质量的材料,并回答大家的各种问题。

在介绍线程堆栈分析技术和问题模式之前,先要给大家讲讲基础的内容。所以在这篇帖子里,我将先覆盖到最基本的内容,这样大家就能更好的去理解JVM、中间件、以及JavaEE容器之间的交互。

JavaVM概述

Java虚拟机是JaveEE平台的基础。它是中间件和应用程序被部署和运行的地方。

JVM向中间件软件和你的Java/JavaEE程序提供了下面这些东西:

_(二进制形式的)Java/JavaEE程序运行环境

_一些程序功能特性和工具(IO基础设施,数据结构,线程管理,安全,监控等等)

_借助垃圾回收的动态内存分配与管理

你的JVM可以驻留在许多的 *** 作系统(Solaris,AIX,Windows等等)之上,并且能根据你的物理服务器配置,你可以在每台物理/虚拟服务器上安装1到多个JVM进程

JVM与中间件之间的交互

下面这张图展示了JVM、中间件和应用程序之间的高层交互模型。

如你所见,标准JavaEE应用程序的线程的分配实在中间件内核与JVM之间完成的。(当然也有例外,应用程序可以直接调用API来创建线程,这种做法并不常见,而且在使用的过程中也要特别的小心)

同时,请注意一些线程是由JVM内部来进行管理的,典型的例子就是垃圾回收线程,JVM内部使用这个线程来做并行的垃圾回收处理。

因为大多数的线程分配都是由JavaEE容器完成的,所以能够理解和认识线程堆栈跟踪,并能从线程堆栈数据中识别出它来,对你而言很重要这可以让你能够快速的知道JavaEE容器正要执行的是什么类型的请求

从一个线程转储堆栈的分析角度来看,你将能了解从JVM发现的线程池之间的不同,并识别出请求的类型

最后一节会向你提供对于HotSopVM而言什么是JVM线程堆栈的一个概述,还有你将会遇到的各种不同的线程而对IBMVM线程堆栈形式详细内容将会在第四节向你提供

请注意你可以从根本原因分析论坛获得针对本文的线程堆栈示例

JVM线程堆栈——它是什么

JVM线程堆栈是一个给定时间的快照,它能向你提供所有被创建出来的Java线程的完整清单

处理器数量 :是指CPU核数(例如:单核/双核),并不是指CPU颗数。\x0d\\x0d\每个处理的核心数量:是指CPU中的线程,并不是指核心(Core)。\x0d\\x0d\自己也可以求证,首先你肯定知道自己物理机CPU 信息(例如I3 双核四线程),在vmware中设置虚拟机处理器数量,从字面意识理解应该是指CPU颗数,正常设置值最大应该为1(因为物理机只有一块CPU),但最大有效值可以设置为2,如果最大值设置为4,下面会提示你多于主机支持数。由此得出结论处理器数量是指CPU核数(core),而并不是CPU颗数。\x0d\\x0d\处理器数量都表示的是核数,那么“每个处理的核心数量”就不是表示核心数量,不然出现两个设置核心数量的参数,不是多此一举?还有一个问题就是你会发现里面有一个3的值,所以就更加肯定不是CPU核数,因为CPU核数除1以外都是偶数增长,对CPU了解的人都会知道CPU核数布局是两排均匀排开的,怎么可能会出现奇数,岂不是浪费掉一个核数位置?\x0d\\x0d\根据你的虚拟机对CPU的需求和当前物理机CPU使用情况来设定“处理器数量”和 “每个处理的核心数量”\x0d\\x0d\XP系统 最小值设定\x0d\处理器数量=1,每个处理的核心数量=2\x0d\\x0d\W7系统最小值设定\x0d\处理器数量=2,每个处理的核心数量=2\x0d\\x0d\还是那句话,看需求设置吧,比如你当前物理机CPU已经使用达到70-80了,那么虚拟机CPU就给核数跟线程数就给少点。\x0d\\x0d\手工码字不容易啊。

品牌型号:华为MateBook D15

系统:Windows 11

电脑线程数是CPU核心数。

CPU的核心数是指物理上,也就是硬件上存在着几个核心。比如,双核就是包括2个相对独立的CPU核心单元组,四核就包含4个相对独立的CPU核心单元组。

CPU之所以要增加线程数,是源于多任务处理的需要。线程数越多,越有利于同时运行多个程序,因为线程数等同于在某个瞬间CPU能同时并行处理的任务数。 因此,线程数是一种逻辑的概念,简单地说,就是模拟出的CPU核心数。一个核心最少对应一个线程,但英特尔有个超线程技术可以把一个物理线程模拟出两个线程来用,充分发挥CPU性能,即一个核心可以有两个到多个线程。

说明:

1、一般初始堆和最大堆设置一样,因为:现在内存不是什么稀缺的资源,但是如果不一样,从初始堆到最大堆的过程会有一定的性能开销,所以一般设置为初始堆和最大堆一样。64位系统理论上可以设置为无限大,但是一般设置为 4G ,因为如果再大,JVM进行垃圾回收出现的暂停时间会比较长,这样全GC过长,影响JVM对外提供服务,所以不能太大。一般设置为4G。

2、-XX:NewRaio和-XX:SurvivorRatio这两个参数,都是设置年轻代和年老代的大小的,设置一个即可,第一是设置年轻代的大小,第二个是设置比值,理论上设置一个既可以满足需求

打印GC回收的过程日志信息

以下配置主要针对分代收集回收算法而言

年轻代的设置很关键

JVM中最大堆大小有三方面限制:相关 *** 作系统的数据模型(32bit还是64bit)限制:系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在15G-2G;64位 *** 作系统对内存没有限制。在Windows Server 2003系统,35G物理内存,JDK50下测试,最大设置为1478m。

典型设置:

JVM给了三种选择:串行收集器,并行收集器,并发收集器,但是串行收集器只适用于小数据量的情况,一般不考虑使用了,所以这里只针对并行收集器和并发收集器。默认情况下,JDK50以前是使用的串行收集器,如果想使用其他收集器需要在启动时加入相应的参数, JDK50以后,JVM会根据系统当前的配置进行判断

吞吐量优先的并行收集器

并行收集器主要以到达一定的吞吐量为目标,适用于后台处理

响应时间优先的并发收集器

并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。

61年轻代大小选择

响应时间优先的应用:尽可能设置大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时减少到达年老代的对象。

吞吐量优先的应用:尽可能的设置大,可能到达Gbit的成都,因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8核CPU以上应用。

62年老代大小选择

响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可能会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考一下数据获得:

1、并发垃圾收集信息

2、持久代并发收集次数

3、传统GC信息

4、花在年轻代和年老代回收上的时间比例减少年轻代和年老代花费的时间,一般会提高应用的效率

63吞吐量优先的应用

一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期对象,而年老代尽存放长期存活的对象

64较小堆引起的碎片问题

因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:

Jconsole,jProfile,VisualVM

Jconsole:jdk自带, 功能简单,但是可以再系统有一定负荷的情况下使用,对垃圾回收算法有很详细的跟踪。

JProfiler:商业软件,需要付费,但是功能强大

VisualVM:JDK自带,功能强大,与Jprofiler类似,推荐

观察内存释放情况、集合类检查,对象树

上面这些调优工具都提供了强大的功能,但是总的来说一般分为以下几类功能:

一般就是根据垃圾回收前后情况对比,同时根据对象引用情况( 常见的集合对象引用 )分析,基本都可以找到泄漏点。

持久代沾满处理:

1、-XX:MaxPermSize=16m

2、换JDK比如:JRocket

系统内存被沾满:

一般是因为没有足够的资源产生线程造成的,系统创建线程时,除了要在Java堆中分配内存外, *** 作系统本身也需要分配资源来创建线程。因此,当线程数量大的一定程度以后,堆中或许还有空间,但是 *** 作系统分配不出资源来了,出现异常。

分配给Java虚拟机的内存越多,系统剩余的资源就越少,因此,当系统内存固定时,分配给Java虚拟机的内存越多,那么,系统总共能够产生的线程也就越少,两者成反比。同事,可以通过修改-Xss来减少分配给单个线程的空间,也可以增加系统总共生产的线程数。

java程序内存问题的诊断方法:

查看jmap的命令参数,帮助查看堆信息

以上就是关于你如何在Java中获取线程堆栈全部的内容,包括:你如何在Java中获取线程堆栈、VMware虚拟机中的“处理器数量”如何设置、电脑线程数是什么意思等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9623303.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存