jvm面试常问
1 设置jvm内存大小xmx, xms, Xss
-Xss:规定了每个线程虚拟机栈及堆栈的大小,一般情况下,256k是足够的,此配置将会影响此进程中并发线程数的大小。
-Xms:表示初始化JAVA堆的大小及该进程刚创建出来的时候,他的专属JAVA堆的大小,一旦对象容量超过了JAVA堆的初始容量,JAVA堆将会自动扩容到-Xmx大小。
-Xmx:表示java堆可以扩展到的最大值,在很多情况下,通常将-Xms和-Xmx设置成一样的,因为当堆不够用而发生扩容时,会发生内存抖动影响程序运行时的稳定性
示例,由于处理inc*99c文件时, 文件大小两百多M, 而jvm中实际内存设置的比较小,需要获取文件尾行数据, 代码中是一次性获取文件流进来的,所以超过了报oom
解决方案设置xmx和xms, 以及通过重置流去获取文件尾行数据
2. jdk自带的visualvm可视化性能监控工具
示例: 当时解析authlog文件时, 由于文件有2个G,解析耗时半个小时,通过查看visualvm监控工具,发现日志打印类比较耗时,
因为代码中每次执行打印则会通过发射去创建日志对象,通过优化, 改成全局静态的去创建日志;
3 jmap命令
jmap: 可以输出指定进程的内存中对象映射信息,或者堆的关键信息、内存的使用统计、GC算法、配置、类的实例信息及内存占用等
$ jmap 1281
$ jmap -heap 1281
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 536870912 (512.0MB)
Heap Usage:
PS Young Generation
Eden Space:
From Space:
To Space:
PS Old Generation
4 jstack命令
输出指定进程当前时刻在JVM中的线程信息,为了清楚的展示其效果,在服务启动时创建线程死锁
,然后通过该命令就会把发生死锁的线程打印出来,通过输出可以发现两条互相等待的线程信息
$ jstack 1281
Found one Java-level deadlock:
=============================
"test-thread-02":
waiting for ownable synchronizer 0x00000007b00a35d0, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "test-thread-01"
"test-thread-01":
waiting for ownable synchronizer 0x00000007b00a35a0, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "test-thread-02"
5 jps命令
虚拟机进程状态工具,该命令在Java环境部署和服务启动查看时经常用到,首先在本地启动一个facade门面微服务,然后在命令行中执行查询;
jps
:命令默认输出的是进程ID和应用主类的名称;-l
:输出进程ID和应用主类的完整路径;-v
:输出向jvm传递的参数,此处展示为idea中显式配置的VM-options参数,其他内容自行查看即可;-m
:输出向main方法传递的参数,服务启动前可以在idea的Program-arguments配置;
$ jps
1281 FacadeApp
$ jps -l
1281 com.explore.facade.FacadeApp
$ jps -v
1281 FacadeApp -Xms128m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
$ jps -m
1281 FacadeApp hello,main-method
6 jstat命令
$ jstat -gcutil 1281 3000 5
以指定的频率输出JVM的监控指标,下述命令输出内存占用和GC相关信息,每隔3秒输出一次,连续打印5次
7 jconsole
Java内置的JVM性能监控工具,在熟悉上述的命令行工具之后,对于该可视化工具的使用不会太陌生
,在命令中可以查看到的默认参数或者应用自定义配置,在该工具中也可以找到,并且以图形化的方式呈现
$ jconsole # 通过该命令会唤起jconsole界面