「java虚拟机启动参数」kvm虚拟机启动参数

博主:adminadmin 2022-12-19 06:57:14 68

今天给各位分享java虚拟机启动参数的知识,其中也会对kvm虚拟机启动参数进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

在新建虚拟机时出现问题?

JConsole

JConsole 图形用户界面是一种符合 Java 管理扩展(JMX)规范的监视工具。JConsole 使用 Java 虚拟机 (Java VM) 的广泛检测来提供有关在 Java 平台上运行的应用程序的性能和资源消耗的信息。

使用方法 本地

使用jconsole命令:监视本地运行的所有 Java 应用程序,JConsole 可以连接到这些应用程序。

使用jconsole PID命令:监视指定PID的Java应用程序。

获取java PID的方法:通过任务管理器查看、通过Java提供的jps命令查看。远程

使用jsconsole hostName:portNum命令:hostName是运行应用程序的系统的名称,portNum是您在启动Java VM时启用 JMX 代理时指定的端口号。

使用service:jmx::命令:使用 JMX 服务 URL 进行连接。

内容分析

将 JConsole 连接到应用程序后,JConsole 由六个选项卡组成。

概述:显示有关 Java VM 和受监视值的概述信息。

内存:显示有关内存使用的信息。

线程:显示有关线程使用的信息。

类:显示有关类加载的信息。

VM:显示有关 Java VM 的信息。

MBeans:显示有关 MBeans 的信息。

组成部分 概览

显示有关 CPU 使用情况、内存使用情况、线程计数和在Java VM中加载的类的图形监视信息。

提供执行GC的操作,可以随时点击按钮进行垃圾回收

伊甸园空间(堆):最初为大多数对象分配内存的池。

幸存者空间(堆):包含在伊甸园空间垃圾回收中幸存下来的物体的池。

终身代(堆):包含在幸存者空间中存在一段时间的对象的池。

永久生成(非堆):包含虚拟机本身的所有反射数据的池,如类和方法对象。使用类数据共享的 Java VM,这一代分为只读和读写区域。

代码缓存(非堆):HotSpotJava VM 还包括一个代码缓存,其中包含用于编译和存储本机代码的内存。

堆和非堆内存

Java VM管理两种类型的内存:堆内存和非堆内存,这两种内存都是在 Java VM 启动时创建的。

堆内存是Java VM为所有类实例和数组分配内存的运行时数据区域。堆的大小可能是固定的或可变的。垃圾回收器是一个自动内存管理系统,用于回收对象的堆内存。

非堆内存包括所有线程之间共享的方法区域和Java VM的内部处理或优化所需的内存。它存储每类结构,如运行时常量池、字段和方法数据,以及方法和构造函数的代码。方法区域在逻辑上是堆的一部分,但是,根据实现,Java VM 可能不会对它进行垃圾回收或压缩。与堆内存一样,方法区域可能为固定大小或可变大小。方法区域的内存不需要连续。

内存池和内存管理器

内存池和内存管理器是Java VM内存系统的关键方面。

内存池表示Java VM管理的内存区域。Java VM至少有一个内存池,它可能会在执行期间创建或删除内存池。内存池可以属于堆内存或非堆内存。

内存管理器管理一个或多个内存池。垃圾回收器是一种内存管理器,负责回收不可到达的对象使用的内存。Java VM可能具有一个或多个内存管理器。它可以在执行期间添加或删除内存管理器。内存池可以由多个内存管理器管理。

垃圾回收

垃圾回收 (GC) 是Java VM释放不再引用的对象占用的内存的方式。通常认为具有活动引用为"活动"且未引用(或无法访问)对象的对象为"已死"。垃圾回收是释放死对象使用的内存的过程。GC 使用的算法和参数对性能有显著影响。

Java hotspot VM垃圾回收器使用代数 GC。生成 GC 利用大多数程序符合以下概括的观察。

它们创建许多寿命较短的对象,例如迭代器和局部变量。

它们创建一些寿命很长的对象,例如高级持久对象。

线程

提供有关线程使用的信息。

查找监视器死锁线程:检测对象监视器锁上是否有任何线程死锁。此操作返回死锁线程指示的数组。

getThreadInfo:返回线程信息。这包括线程当前被阻止的名称、堆栈跟踪和监视器锁(如果有)以及持有该锁的线程以及线程争用统计信息。

获取ThreadCpu时间:返回给定线程消耗的 CPU 时间

显示有关类加载的信息。

提供有关Java VM的信息。

以通用方式显示有关在平台 MBean 服务器注册的所有 MBeans 的信息。MBeans 选项卡允许您访问平台 MXBean 检测的完整集,包括在其他选项卡中不可见的仪器。此外,您还可以使用 MBeans 选项卡监视和管理应用程序的 MBeans。

列出目标系统上已检测的 Java 虚拟机 (JVM)。

监视 Java 虚拟机 (JVM) 统计信息。

对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。

命令格式

jstat [-option] [PID]

option参数

class:显示有关类加载器行为的统计信息。

compiler:显示有关Java HotSpot VM实时编译器行为的统计信息。

gc:显示有关垃圾回收堆行为的统计信息。

gccapacity:显示有关几代人容量及其相应空间的统计信息。

gccause:显示有关垃圾回收统计信息(与 相同)的摘要,以及最后和当前(如果适用)垃圾回收事件的原因。-gcutil

gcnew:显示新一代行为的统计信息。

gcnewcapacity:显示有关新一代大小及其相应空间的统计信息。

gcold:显示有关旧一代和元空间统计信息行为的统计信息。

gcoldcapacity:显示有关旧一代大小的统计信息。

gcmetacapacity:显示有关元空间大小的统计信息。

gcutil:显示有关垃圾回收统计信息的摘要。

printcompilation:显示 Java 热点 VM 编译方法统计信息。

1.jstat –class: 显示加载class的数量,及所占空间等信息。

2.jstat -compiler显示VM实时编译的数量等信息。

3.jstat -gc: 可以显示gc的信息,查看gc的次数,及时间。

4.jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小

5.jstat -gcutil:统计gc信息

6.jstat -gcnew:年轻代对象的信息。

7.jstat -gcnewcapacity: 年轻代对象的信息及其占用量。

8.jstat -gcold:old代对象的信息。

9.jstat -gcoldcapacity: old代对象的信息及其占用量。

10.jstat -gcpermcapacity: perm对象的信息及其占用量。

11.jstat -printcompilation:当前VM执行的信息。

监视 Java 虚拟机 (JVM),并使远程监视工具能够连接到 JVM

命令格式

jstatd -[option]

option

-nr当找不到现有的RMI注册表时,不尝试使用jstatd进程创建一个内部的RMI注册表。

-p port在指定的端口查找RMI注册表。如果没有找到,并且没有指定-nr选项,则在该端口自行创建一个内部的RMI注册表。

-n rminameRMI注册表中绑定的RMI远程对象的名称。默认的名称为JStatRemoteHost。如果多个jstatd服务器在同一主机上运行,你可以通过指定该选项来让每个服务器导出的RMI对象具有唯一的名称。不管如何,这样做需要将唯一的服务器名称包含进监控客户端的hostid和vmid字符串中。

-Joption将选项参数传递给被javac调用的java启动程序。例如,-J-Xms48m设置启动内存为48 MB。使用-J将选项参数传递给执行Java应用程序的底层虚拟机,这是一种常见惯例。

使用方法

1.在jdk的bin目录下创建文件jstatd.all.policy

2.写入下面的安全配置

grant codebase "file:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/lib/tools.jar" {

permission java.security.AllPermission;

#此处写绝对路径,主要是防止路径错误问题,排查问题,应该写成相对路径

3.启动jstatd

./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=x.x.x.x

4.使用jvisualvm工具远程连接,进行监控

jvisualvm

VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的).

同时他还提供很多插件可以自己安装,是一款不错的监控分析工具。

故障排除工具 JInfo

可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息

命令格式

参数说明

pid对应jvm的进程id

executable core产生core dump文件

[server-id@]remote server IP or hostname远程的ip或者hostname,server-id标记服务的唯一性id

option

no option输出全部的参数和系统属性

-flag name输出对应名称的参数

-flag [+|-]name开启或者关闭对应名称的参数

-flag name=value设定对应名称的参数

-flags输出全部的参数

-sysprops输出系统属性

Javacore 概述

Javacore,也可以称为“threaddump”或是“javadump”,它是 Java 提供的一种诊断特性,能够提供一份可读的当前运行的 JVM 中线程使用情况的快照。即在某个特定时刻,JVM 中有哪些线程在运行,每个线程执行到哪一个类,哪一个方法。应用程序如果出现不可恢复的错误或是内存泄露,就会自动触发 Javacore 的生成。

使用方法

1.jinfo pid:输出当前 jvm 进程的全部参数和系统属性

2.jinfo -flag name pid:输出对应名称的参数使用该命令,可以查看指定的 jvm 参数的值。如:查看当前 jvm 进程是否开启打印 GC 日志。

3.jinfo -flag [+|-]name pid:开启或者关闭对应名称的参数

使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用。

4.jinfo -flag name=value pid:修改指定参数的值。

注意:jinfo虽然可以在java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改

5.jinfo -flags pid:输出全部的参数

6.jinfo -sysprops pid:输出当前 jvm 进行的全部的系统属性

jhat

主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。

1.使用jmap命令导出堆文件jmap -dump:live,file=a.log pid

也可以使用下面方式导出堆文件

1、使用jconsole选项通过HotSpotDiagnosticMXBean从运行时获得堆转储(生成dump文件)、

2、虚拟机启动时如果指定了-XX:+HeapDumpOnOutOfMemoryError选项, 则在抛出OutOfMemoryError时, 会自动执行堆转储。

3、使用hprof命令

2.使用jhat分析堆文件jhat -J-Xmx512M a1.log

3.查看分析的html页面

中的OQL(对象查询语言)

如果需要根据某些条件来过滤或查询堆的对象,这是可能的,可以在jhat的html页面中执行OQL,来查询符合条件的对象

基本语法:

select

[from [instanceof] ]

[where ]

解释:

(1)class name是java类的完全限定名,如:java.lang.String,java.util.ArrayList, C是char数组,java.io.File是java.io.File[]

(2)类的完全限定名不足以唯一的辨识一个类,因为不同的ClassLoader载入的相同的类,它们在jvm中是不同类型的

(3)instanceof表示也查询某一个类的子类,如果不明确instanceof,则只精确查询class name指定的类

(4)from和where子句都是可选的

(5)java域表示:obj.field_name;java数组表示:array[index]

举例:

(1)查询长度大于100的字符串

select s from java.lang.String s where s.count 100

(2)查询长度大于256的数组

select a from [I a where a.length 256

(3)显示匹配某一正则表达式的字符串

select a.value.toString() from java.lang.String s where /java/(s.value.toString())

(4)显示所有文件对象的文件路径

select file.path.value.toString() from java.io.File file

(5)显示所有ClassLoader的类名

select classof(cl).name from instanceof java.lang.ClassLoader cl

(6)通过引用查询对象

select o from instanceof 0xd404d404 o

built-in对象 -- heap

(1)heap.findClass(class name) -- 找到类

select heap.findClass("java.lang.String").superclass

(2)heap.findObject(object id) -- 找到对象

select heap.findObject("0xd404d404")

(3)heap.classes -- 所有类的枚举

select heap.classes

(4)heap.objects -- 所有对象的枚举

select heap.objects("java.lang.String")

(5)heap.finalizables -- 等待垃圾收集的java对象的枚举

(6)heap.livepaths -- 某一对象存活路径

select heaplivepaths(s) from java.lang.String s

(7)heap.roots -- 堆根集的枚举

辨识对象的函数

(1)classof(class name) -- 返回java对象的类对象

select classof(cl).name from instanceof java.lang.ClassLoader cl

(2)identical(object1,object2) -- 返回是否两个对象是同一个实例

select identical(heap.findClass("java.lang.String").name, heap.findClass("java.lang.String").name)

(3)objectid(object) -- 返回对象的id

select objectid(s) from java.lang.String s

(4)reachables -- 返回可从对象可到达的对象

select reachables(p) from java.util.Properties p -- 查询从Properties对象可到达的对象

select reachables(u, "java.net.URL.handler") from java.net.URL u -- 查询从URL对象可到达的对象,但不包括从URL.handler可到达的对象

(5)referrers(object) -- 返回引用某一对象的对象

select referrers(s) from java.lang.String s where s.count 100

(6)referees(object) -- 返回某一对象引用的对象

select referees(s) from java.lang.String s where s.count 100

(7)refers(object1,object2) -- 返回是否第一个对象引用第二个对象

select refers(heap.findObject("0xd4d4d4d4"),heap.findObject("0xe4e4e4e4"))

(8)root(object) -- 返回是否对象是根集的成员

select root(heap.findObject("0xd4d4d4d4"))

(9)sizeof(object) -- 返回对象的大小

select sizeof(o) from [I o

(10)toHtml(object) -- 返回对象的html格式

select "+ toHtml(o) + "" from java.lang.Object o

(11)选择多值

select {name:t.name?t.name.toString():"null",thread:t} from instanceof java.lang.Thread t

数组、迭代器等函数

(1)concat(enumeration1,enumeration2) -- 将数组或枚举进行连接

select concat(referrers(p),referrers(p)) from java.util.Properties p

(2)contains(array, expression) -- 数组中元素是否满足某表达式

select p from java.util.Properties where contains(referres(p), "classof(it).name == 'java.lang.Class'")

返回由java.lang.Class引用的java.util.Properties对象

built-in变量

it -- 当前的迭代元素

index -- 当前迭代元素的索引

array -- 被迭代的数组

(3)count(array, expression) -- 满足某一条件的元素的数量

select count(heap.classes(), "/java.io./(it.name)")

(4)filter(array, expression) -- 过滤出满足某一条件的元素

select filter(heap.classes(), "/java.io./(it.name)")

(5)length(array) -- 返回数组长度

select length(heap.classes())

(6)map(array,expression) -- 根据表达式对数组中的元素进行转换映射

select map(heap.classes(),"index + '--' + toHtml(it)")

(7)max(array,expression) -- 最大值, min(array,expression)

select max(heap.objects("java.lang.String"),"lhs.countrhs.count")

built-in变量

lhs -- 左边元素

rhs -- 右边元素

(8)sort(array,expression) -- 排序

select sort(heap.objects('[C'),'sizeof(lhs)-sizeof(rhs)')

(9)sum(array,expression) -- 求和

select sum(heap.objects('[C'),'sizeof(it)')

(10)toArray(array) -- 返回数组

(11)unique(array) -- 唯一化数组

jmap

打印进程、核心文件或远程调试服务器的共享对象内存映射或堆内存详细信息。

jmap [option]

(to connect to running process) 连接到正在运行的进程

jmap [option]

(to connect to a core file) 连接到核心文件

jmap [option] [server_id@]

(to connect to remote debug server) 连接到远程调试服务

option

pid:目标进程的PID,进程编号,可以采用ps -ef | grep java查看java进程的PID;

executable:产生core dump的java可执行程序;

core:将被打印信息的core dump文件;

remote-hostname-or-IP:远程debug服务的主机名或ip;

server-id:唯一id,假如一台主机上多个远程debug服务;

使用方法

jmap -dump:[live,]format=b,file= PID:使用hprof二进制形式,输出jvm的heap内容到文件

jmap -finalizerinfo PID:打印正等候回收的对象的信息

jmap -heap PID:打印heap的概要信息,GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况。

jmap -histo:live PID:打印每个class的实例数目,内存占用,类全名信息。VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.

jmap -permstat PID:打印classload和jvm heap长久层的信息. 包含每个classloader的名字、活泼性、地址、父classloader和加载的class数量。另外,内部String的数量和占用内存数也会打印出来。

-F强迫.在pid没有相应的时候使用-dump或者-histo参数。在这个模式下,live子参数无效。

-h | -help打印辅助信息

-J传递参数给jmap启动的jvm.

jstack

jstack命令主要用于调试java程序运行过程中的线程堆栈信息,可以用于检测死锁,进程耗用cpu过高报警问题的排查。jstack命令会打印出所有的线程,包括用户自己启动的线程和jvm后台线程。

命令格式

jstack -[option] pid

option

-F强制dump线程堆栈信息. 用于进程hung住,jstack命令没有响应的情况

-m同时打印java和本地(native)线程栈信息,m是mixed mode的简写

-l打印锁的额外信

作者:楚瑞涛

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

------ 特别推荐 ------

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注。

文章有帮助的话,在看,转发吧!

如何查看java虚拟机堆内存的参数值

请确保java_home/bin配置到path环境变量下,因为这些工具都在jdk的bin目录下

jps(JVM Process Status Tool):JVM机进程状况工具

用来查看基于HotSpot JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等。与unix上的ps类似,用来显示本地有权限的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。使用jps时,不需要传递进程号做为参数。

Jps也可以显示远程系统上的JAVA进程,这需要远程服务上开启了jstat服务,以及RMI注及服务,不过常用都是对本对的JAVA进程的查看。

命令格式:jps [ options ] [ hostid ]

常用参数说明:

-m 输出传递给main方法的参数,如果是内嵌的JVM则输出为null。

-l 输出应用程序主类的完整包名,或者是应用程序JAR文件的完整路径。

-v 输出传给JVM的参数。

例如:

C:\Users\Administratorjps -lmv

1796 -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m -XX:MaxPermSize=256m

7340 sun.tools.jps.Jps -lmv -Denv.class.path=.;D:\DevTools\VM\jdk1.6.0_31\\lib\dt.jar;D:\DevTools\VM\jdk1.6.0_31\\lib\tools.jar; -Dapplication.home=D:\DevTools\VM\jdk1.6.0_31 -Xms8m

其中pid为1796的是我的eclipse进程,pid为7340的是jps命令本身的进程

jinfo(Configuration Info for Java):JVM配置信息工具

可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数

命令格式:jinfo [ options ] [ pid ]

常用参数说明:

-flag 输出,修改,JVM命令行参数

例如:

C:\Users\Administratorjinfo 1796

将会打印出很多jvm运行时参数信息,由于比较长这里不再打印出来,可以自己试试,内容一目了然

Jstack(Stack Trace for Java):JVM堆栈跟踪工具

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64“

命令格式:jstack [ option ] pid

常用参数说明:

-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息

-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.

-m 打印java和native c/c++框架的所有栈信息.

-h | -help打印帮助信息

例如:

C:\Users\Administratorjstack 1796

2013-05-22 11:42:38

Full thread dump Java HotSpot(TM) Client VM (20.6-b01 mixed mode):

"Worker-30" prio=6 tid=0x06514c00 nid=0x1018 in Object.wait() [0x056af000]

java.lang.Thread.State: TIMED_WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:188)

- locked 0x1ad84a90 (a org.eclipse.core.internal.jobs.WorkerPool)

at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:220)

at org.eclipse.core.internal.jobs.Worker.run(Worker.java:50)

......

......

......

......

jstat(JVM statistics Monitoriing Tool):JVM统计信息监视工具

对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控

命令格式:jstat [ option pid [interval [ s | ms ] [count] ] ]

常用参数说明:

-gcutil 输出已使用空间占总空间的百分比

-gccapacity 输出堆中各个区域使用到的最大和最小空间

例如:每隔1秒监控jvm内存一次,共监控5次

C:\Users\Administratorjstat -gccapacity 1796 1s 5

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC

13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96

13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96

13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96

13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96

13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 97

C:\Users\Administratorjstat -gcutil 1796 1s 5

S0 S1 E O P YGC YGCT FGC FGCT GCT

0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632

0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632

0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632

0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632

0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632

一些术语的中文解释:

S0C:年轻代中第一个survivor(幸存区)的容量 (字节)

S1C:年轻代中第二个survivor(幸存区)的容量 (字节)

S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)

S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)

EC:年轻代中Eden(伊甸园)的容量 (字节)

EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)

OC:Old代的容量 (字节)

OU:Old代目前已使用空间 (字节)

PC:Perm(持久代)的容量 (字节)

PU:Perm(持久代)目前已使用空间 (字节)

YGC:从应用程序启动到采样时年轻代中gc次数

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)

FGC:从应用程序启动到采样时old代(全gc)gc次数

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT:从应用程序启动到采样时gc用的总时间(s)

NGCMN:年轻代(young)中初始化(最小)的大小 (字节)

NGCMX:年轻代(young)的最大容量 (字节)

NGC:年轻代(young)中当前的容量 (字节)

OGCMN:old代中初始化(最小)的大小 (字节)

OGCMX:old代的最大容量 (字节)

OGC:old代当前新生成的容量 (字节)

PGCMN:perm代中初始化(最小)的大小 (字节)

PGCMX:perm代的最大容量 (字节)

PGC:perm代当前新生成的容量 (字节)

S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比

S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比

E:年轻代中Eden(伊甸园)已使用的占当前容量百分比

O:old代已使用的占当前容量百分比

P:perm代已使用的占当前容量百分比

S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)

S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)

ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)

DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)

TT: 持有次数限制

MTT : 最大持有次数限制

jmap( Memory Map for Java):JVM内存映像工具

打印出某个java进程(使用pid)内存内的所有‘对象’的情况(如:产生那些对象,及其数量)

命令格式:jmap [ option ] pid

常用参数说明:

-dump:[live,]format=b,file=filename 使用二进制形式输出jvm的heap内容到文件中, live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.

-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.

-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.

例如:以二进制形式输入当前堆内存映像到文件data.hprof中

jmap -dump:live,format=b,file=data.hprof 1796

生成的文件可以使用jhat工具进行分析,在OOM(内存溢出)时,分析大对象,非常有用

通过使用如下参数启动JVM,也可以获取到dump文件:

-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=./java_pidpid.hprof

在jvm发生内存溢出时生成内存映像文件

jhat(JVM Heap Analysis Tool):JVM堆转储快照分析工具

用于对JAVA heap进行离线分析的工具,他可以对不同虚拟机中导出的heap信息文件进行分析,如LINUX上导出的文件可以拿到WINDOWS上进行分析,可以查找诸如内存方面的问题。

命令格式:jhat dumpfile(jmap生成的文件)

例如:分析jmap导出的内存映像

jhat data.hprof

执行成功后,访问即可查看内存信息,

MAT(Memory Analyzer Tool):一个基于Eclipse的内存分析工具

官网:

update:

这是eclipse的一个插件,安装后可以打开xxx.hprof文件,进行分析,比jhat更方便使用,有些时候由于线上xxx.hprof文件过大,直接使用jhat进行初步分析了,可以的话拷贝到本地分析效果更佳。

图形化监控工具:

在JDK安装目录bin下面有两个可视化监控工具

1. JConsole(Java Monitoring and Management Console) 基于JMX的可视化管理工具。

2. VisualVM(All-in-one Java Troubleshooting Tool)随JDK发布的最强大的运行监视和故障处理程序。

推荐使用VisualVM,他有很多插件,可以更方便的监控运行时JVM

如何检查和解决java虚拟机内存溢出的问题

一,jvm内存区域

1, 程序计数器

一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器。

2, java栈

与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同。通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址)

栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常;如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

3, 本地方法栈

与虚拟机栈作用很相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则是为虚拟机用到的Native方法服务。和虚拟机栈一样可能抛出StackOverflowError和OutOfMemoryError异常。

4, java堆

java

Heap是jvm所管理的内存中最大的区域。JavaHeap是被所有线程共享的一块内存区域,在虚拟机启动时创建。主要存放对象实例。JavaHeap

是垃圾收集器管理的主要区域,其可细分为新生代和老年代。如果在堆中没有内存完成实例分配,并且也无法再扩展时,会抛出OutOfMemoryError

异常。

5, 方法区

与javaHeap一样是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。当方法区无法满足内

存分配的需求时,将抛出OutOfMemoryError异常。方法同时包含常听说的运行时常量池,用于存放编译期生成的各种字面量和符号引用。

6, 直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,是jvm外部的内存区域,这部分区域也可能导致OutOfMemoryError异常。

二,jvm参数

-Xss(StackSpace)栈空间

-Xms ,-Xmx(heap memory

space)堆空间:Heap是大家最为熟悉的区域,他是jvm用来存储对象实例的区域,Heap在32位的系统中最大为2G,其大小通过-Xms和

-Xmx来控制,-Xms为jvm启动时申请的最小Heap内存,默认为物理内存的1/64,但小于1G,-Xmx为jvm可申请的最大的Heap内存,

默认为物理内存的1/4,一般也小于1G,默认当空余堆内存小于40%时,jvm会最大Heap的大小到-Xmx指定大小,可通过

-XX:MinHeapFreeRatio来指定这个比例,当空余堆内存大于70%时,JVM会将Heap的大小往-Xms指定的大小调整,可通过

-XX:MaxHeapFreeRatio来指定这个比例,但通常为了避免频繁调整HeapSize的大小,将-Xms和-Xmx的值设为相同。

-XX:PermSize -XX:MaxPermSize :方法区持久代大小: 方法区域也是全局共享的,在一定的条件下它也会被 GC ,当方法区域需要使用的内存超过其允许的大小时,会抛出 OutOfMemory 的错误信息。

三,常见内存溢出错误解决办法

1, OutOfMemoryError异常

除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能,

Java Heap 溢出

一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess

java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。

出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory

Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory

Leak)还是内存溢出(Memory Overflow)。

如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链。于是就能找到泄漏对象时通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。

如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。

2, 虚拟机栈和本地方法栈溢出

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

这里需要注意当栈的大小越大可分配的线程数就越少。

3, 运行时常量池溢出

异常信息:java.lang.OutOfMemoryError:PermGen space

如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于

此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String

对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量

池的容量。

4, 方法区溢出

方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。

异常信息:java.lang.OutOfMemoryError:PermGen space

方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。

如何设置Java虚拟机JVM启动内存参数

-Xmx Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;

-Xms Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;

-Xmn Java Heap Young区大小,不熟悉最好保留默认值;

-Xss 每个线程的Stack大小,不熟悉最好保留默认值;

2. 如何设置JVM内存分配:

(1)当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效):

java -Xmx128m -Xms64m -Xmn32m -Xss16m Test

(2)当在集成开发环境下(如eclipse)启动并使用JVM时:

a. 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配)

如何设置java虚拟机参数

java进程命令行使用方式如下:

java [-options] class [args...]

-options 表示虚拟机的启动参数,

class为带有main()函数的java类的全名称

args表示传递给主函数main()的参数 多个用空格 分割即可。

什么是Java虚拟机?

虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

这种解释应该算是正确的,但是只描述了虚拟机的外部行为和功能,并没有针对内部原理做出说明。一般情况下我们不需要知道虚拟机的运行原理,只要专注写java代码就可以了,这也正是虚拟机之所以存在的原因--屏蔽底层操作系统平台的不同并且减少基于原生语言开发的复杂性,使java这门语言能够跨各种平台(只要虚拟机厂商在特定平台上实现了虚拟机),并且简单易用。这些都是虚拟机的外部特性,但是从这些信息来解释虚拟机,未免太笼统了,无法让我们知道内部原理。

从进程的角度解释JVM

让我们尝试从操作系统的层面来理解虚拟机。我们知道,虚拟机是运行在操作系统之中的,那么什么东西才能在操作系统中运行呢?当然是进程,因为进程是操作系统中的执行单位。可以这样理解,当它在运行的时候,它就是一个操作系统中的进程实例,当它没有在运行时(作为可执行文件存放于文件系统中),可以把它叫做程序。

对命令行比较熟悉的同学,都知道其实一个命令对应一个可执行的二进制文件,当敲下这个命令并且回车后,就会创建一个进程,加载对应的可执行文件到进程的地址空间中,并且执行其中的指令。下面对比C语言和Java语言的HelloWorld程序来说明问题。

首先编写C语言版的HelloWorld程序。

编译C语言版的HelloWorld程序:

gcc HelloWorld.c -o HelloWorld

运行C语言版的HelloWorld程序:

zhangjg@linux:/deve/workspace/HelloWorld/src$ ./HelloWorld

hello world

gcc编译器编译后的文件直接就是可被操作系统识别的二进制可执行文件,当我们在命令行中敲下 ./HelloWorld这条命令的时候, 直接创建一个进程, 并且将可执行文件加载到进程的地址空间中, 执行文件中的指令。

作为对比, 我们看一下Java版HelloWord程序的编译和执行形式。

首先编写源文件HelloWord.java :

编译Java版的HelloWorld程序:

运行Java版的HelloWorld程序:

zhangjg@linux:/deve/workspace/HelloJava/src$ java -classpath . HelloWorld

HelloWorld

从上面的过程可以看到, 我们在运行Java版的HelloWorld程序的时候, 敲入的命令并不是 ./HelloWorld.class 。 因为class文件并不是可以直接被操作系统识别的二进制可执行文件 。 我们敲入的是java这个命令。 这个命令说明, 我们首先启动的是一个叫做java的程序, 这个java程序在运行起来之后就是一个JVM进程实例。

上面的命令执行流程是这样的:

java命令首先启动虚拟机进程,虚拟机进程成功启动后,读取参数“HelloWorld”,把他作为初始类加载到内存,对这个类进行初始化和动态链接(关于类的初始化和动态链接会在后面的博客中介绍),然后从这个类的main方法开始执行。也就是说我们的.class文件不是直接被系统加载后直接在cpu上执行的,而是被一个叫做虚拟机的进程托管的。首先必须虚拟机进程启动就绪,然后由虚拟机中的类加载器加载必要的class文件,包括jdk中的基础类(如String和Object等),然后由虚拟机进程解释class字节码指令,把这些字节码指令翻译成本机cpu能够识别的指令,才能在cpu上运行。

从这个层面上来看,在执行一个所谓的java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程,而不是我们写的一个个的class文件。这个叫做虚拟机的进程处理一些底层的操作,比如内存的分配和释放等等。我们编写的class文件只是虚拟机进程执行时需要的“原料”。这些“原料”在运行时被加载到虚拟机中,被虚拟机解释执行,以控制虚拟机实现我们java代码中所定义的一些相对高层的操作,比如创建一个文件等,可以将class文件中的信息看做对虚拟机的控制信息,也就是一种虚拟指令。

编程语言也有自己的原理, 学习一门语言, 主要是把它的原理搞明白。 看似一个简单的HelloWorld程序, 也有很多深入的内容值得剖析。

JVM体系结构简介

为了展示虚拟机进程和class文件的关系,特意画了下面一张图:

根据上图表达的内容,我们编译之后的class文件是作为Java虚拟机的原料被输入到Java虚拟机的内部的,那么具体由谁来做这一部分工作呢?其实在Java虚拟机内部,有一个叫做类加载器的子系统,这个子系统用来在运行时根据需要加载类。注意上面一句话中的“根据需要”四个字。在Java虚拟机执行过程中,只有他需要一个类的时候,才会调用类加载器来加载这个类,并不会在开始运行时加载所有的类。就像一个人,只有饿的时候才去吃饭,而不是一次把一年的饭都吃到肚子里。一般来说,虚拟机加载类的时机,在第一次使用一个新的类的时候。本专栏后面的文章会具体讨论Java中的类加载器。

由虚拟机加载的类,被加载到Java虚拟机内存中之后,虚拟机会读取并执行它里面存在的字节码指令。虚拟机中执行字节码指令的部分叫做执行引擎。就像一个人,不是把饭吃下去就完事了,还要进行消化,执行引擎就相当于人的肠胃系统。在执行的过程中还会把各个class文件动态的连接起来。关于执行引擎的具体行为和动态链接相关的内容也会在本专栏后续的文章中进行讨论。

我们知道,Java虚拟机会进行自动内存管理。具体说来就是自动释放没有用的对象,而不需要程序员编写代码来释放分配的内存。这部分工作由垃圾收集子系统负责。

从上面的论述可以知道, 一个Java虚拟机实例在运行过程中有三个子系统来保障它的正常运行,分别是类加载器子系统, 执行引擎子系统和垃圾收集子系统。 如下图所示:

虚拟机的运行,必须加载class文件,并且执行class文件中的字节码指令。它做这么多事情,必须需要自己的空间。就像人吃下去的东西首先要放在胃中。虚拟机也需要空间来存放个中数据。首先,加载的字节码,需要一个单独的内存空间来存放;一个线程的执行,也需要内存空间来维护方法的调用关系,存放方法中的数据和中间计算结果;在执行的过程中,无法避免的要创建对象,创建的对象需要一个专门的内存空间来存放。关于虚拟机运行时数据区的内容,也会出现在本专栏后续的文章中。虚拟机的运行时内存区大概可以分成下图所示的几个部分。(这里只是大概划分,并没有划分的很精细)

总结

写到这里,基本上关于我对java虚拟机的理解就写完了。这篇文章的主题虽然是深入理解Java虚拟机,但是你可能感觉一点也不“深入”,也只是泛泛而谈。我也有这样的感觉。限于自己水平有限,也只能这样了,要是想深入理解java虚拟机,强烈建议读一下三本书:

《深入Java虚拟机》

《深入理解Java虚拟机JVM高级特性与最佳实践》

《Java虚拟机规范》

其实我也读过这几本书,但是它们对虚拟机的解释也是基于一个外部模型,而没有深入剖析虚拟机内部的实现原理。虚拟机是一个大而复杂的东西,实现虚拟机的人都是大牛级别的,如果不是参与过虚拟机的实现,应该很少有人能把它参透。本专栏后面的一些文章也参考了这三本书, 虽然讲解Java语法的书不计其数, 但是深入讲解虚拟机的书, 目前为止我就见过这三本,并且网上的资料也不是很多。

最后做一个总结:

1 虚拟机并不神秘,在操作系统的角度看来,它只是一个普通进程。

2 这个叫做虚拟机的进程比较特殊,它能够加载我们编写的class文件。如果把JVM比作一个人,那么class文件就是我们吃的食物。

3 加载class文件的是一个叫做类加载器的子系统。就好比我们的嘴巴,把食物吃到肚子里。

4 虚拟机中的执行引擎用来执行class文件中的字节码指令。就好比我们的肠胃,对吃进去的食物进行消化。

5 虚拟机在执行过程中,要分配内存创建对象。当这些对象过时无用了,必须要自动清理这些无用的对象。清理对象回收内存的任务由垃圾收集器负责。就好比人吃进去的食物,在消化之后,必须把废物排出体外,腾出空间可以在下次饿的时候吃饭并消化食物。

扩展资料:

关于JAVA虚拟机的参数说明如下:

1、运行class文件

执行带main方法的class文件,Java虚拟机[3] 命令参数行为:

java CLASS文件名

注意:CLASS文件名不要带文件后缀.class

例如:

java Test

如果执行的class文件是带包的,即在类文件中使用了:

package ;包名

那应该在包的基路径下执行,Java虚拟机命令行参数:

java ;包名.CLASS文件名

例如:

PackageTest.java中,其包名为:com.ee2ee.test,对应的语句为:

package com.ee2ee.test;

PackageTest.java及编译后的class文件PackageTest.class的存放目录如下:

classes

|__com

|__ee2ee

|__test

|__PackageTest.java

|__PackageTest.class

要运行PackageTest.class,应在classes目录下执行:

java com.ee2ee.test.PackageTest

2、运行jar文件中的class

原理和运行class文件一样,只需加上参数-cp jar文件名;即可。

例如:执行test.jar中的类com.ee2ee.test.PackageTest,命令行如下:

java -cp test.jar com.ee2ee.test.PackageTest

3、显示JDK版本信息

当一台机器上有多个jdk版本时,需要知道当前使用的是那个版本的jdk,使用参数-version即可知道其版本,命令行为:

java -version

4、增加虚拟机可以使用的最大内存

Java虚拟机可使用的最大内存是有限制的,缺省值通常为64MB或128MB。

如果一个应用程序为了提高性能而把数据加载内存中而占用较大的内存,比如超过了默认的最大值128MB,需要加大java虚拟机可使用的最大内存,否则会出现Out of Memory的异常。启动java时,需要使用如下两个参数:

-Xms java虚拟机初始化时使用的内存大小

-Xmx java虚拟机可以使用的最大内存

以上两个命令行参数中设置的size,可以带单位,例如:256m表示256MB

举例说明:

java -Xms128m -Xmx256m ...

表示Java虚拟机初始化时使用的内存为128MB,可使用的最大内存为256MB。

对于tomcat,可以修改其脚本catalina. sh(Unix平台)或catalina.bat(Windows平台),设置变量JAVA_OPTS即可,例如:

JAVA_OPTS='-Xms128m -Xmx256m'

参考资料:百度百科-java虚拟机

关于java虚拟机启动参数和kvm虚拟机启动参数的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-19,除非注明,否则均为首码项目网原创文章,转载请注明出处。