一、调优命令
Sun JDK监控和故障处理命令有jps、jstat、jmap、jhat、jstack、jinfo
-
jps
,JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。 -
jstat
,JVM statistics Monitoring是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。 -
jmap
,JVM Memory Map命令用于生成heap dump文件 -
jhat
,JVM Heap Analysis Tool命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看 -
jstack
,用于生成java虚拟机当前时刻的线程快照。 -
jinfo
,JVM Configuration info 这个命令作用是实时查看和调整虚拟机运行参数。
二、调优工具
常用调优工具分为两类,jdk自带监控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer Tool)、GChisto。
-
jconsole
,Java Monitoring and Management Console是从java5开始,在JDK中自带的java监控和管理控制台,用于对JVM中内存,线程和类等的监控。 -
jvisualvm
,jdk自带全能工具,可以分析内存快照、线程快照,监控内存变化、GC变化等。 -
MAT
,Memory Analyzer Tool,一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。 -
GChisto
,一款专业分析gc日志的工具。
三、你知道哪些JVM性能调优
1、设定堆内存大小
-Xmx:堆内存最大限制。
2、设定新生代大小
新生代不宜太小(
可以提高Eden的大小,减少对象进入老年代
),否则会有大量对象涌入老年代
-XX:NewSize:新生代大小
-XX:NewRatio:新生代和老生代占比
-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比
3、设定垃圾回收器
年轻代用 -XX:+UseParNewGC
年老代用 -XX:+UseConcMarkSweepGC
4、Minor GC与Full GC分别在什么时候发生?
Minor GC和Full GC都是Java中垃圾回收的过程。
Minor GC指年轻代的垃圾回收,它会清理Eden区和Survivor区,而不会清理老年代
。Full GC则是对整个堆空间的垃圾回收,包括清理年轻代和老年代、方法区
。Minor GC通常发生在Eden区满时,而Full GC则可能在老年代空间不足时进行。具体来说,Minor GC发生的频率较高,且清理的空间较小,所以它的速度较快,对系统的暂停时间较短;而Full GC发生的频率较低,但清理的空间较大,所以它的速度较慢,对系统的暂停时间也相对较长,应尽量避免Full GC的频繁发生
。
5、JVM手动指定堆内存大小
![](https://img.haomeiwen.com/i26777047/e35ed21945a2fd99.png)
6、JVM是如何避免Minor GC时扫描全堆的?
JVM使用复制算法来避免Minor GC时扫描全堆,即将年轻代分为Eden区和两个Survivor区,在Minor GC时只扫描这三个区域,将存活对象移动到另一个Survivor区中。这种方式可以快速清理出不再使用的对象,同时避免了扫描全堆的开销。
7、JVM内存优化方式包括以下几种:
设置合适的-Xms和-Xmx参数
,合理配置初始堆大小和最大堆大小,以达到内存利用的最优状态。
对象池技术
,通过复用对象,减少对象的创建和销毁,从而节省内存空间。
垃圾回收算法的选择
,比如根据应用的特点选用适合的垃圾收集器,或者在JVM启动时指定合适的GC策略,以提升内存利用率。
对象的生命周期管理
,关闭不再使用的资源,及时释放内存,避免内存泄漏。
编码优化
,使用基本数据类型代替对应的封装类型,避免不必要的对象创建和销毁。
模块化设计
,将复杂的系统分为若干简单的模块,降低模块之间的依赖,减少内存消耗。
综上所述,通过合理的堆大小配置、对象池技术、垃圾回收算法选择、生命周期管理、编码优化和模块化设计,我们可以在一定程度上提高JVM的内存利用率。
8、JVM的永久代中会发生垃圾回收么?
- 在Java 8之前,JVM的永久代是用于存储类、方法、常量等元数据的区域。由于元数据的不断增加,会导致永久代内存不足或溢出,从而引起垃圾回收。但是,永久代的垃圾回收并不同于堆内存的垃圾回收,不存在停顿时间上的限制
(会垃圾回收)
。- JVM 的永久代(PermGen)在 Java 8 以后已被移除,而元空间(Metaspace)是一块独立的内存区域,所以在 Java 8 以后的版本中,
已经不存在永久代的垃圾回收问题了
。
注意:从 Java 8 开始,永久代(PermGen)已被移除,取而代之的是使用元空间(Metaspace)来进行存储。元空间是和 Java 堆(Heap)区分开来的另外一块内存区域,用来存储类元数据、常量池等信息,它的大小是由系统内存来动态分配的。
相对于永久代(PermGen),元空间(Metaspace)有以下几点优势:
可以设置元空间大小的上限,如果元空间满了,将自动进行扩容;
永久代(PermGen)有一些明显的问题,比如内存泄漏、并发访问等,而元空间(Metaspace)则可以更好地解决这些问题;
永久代(PermGen)是 JVM 内存布局中的一个组成部分,而元空间(Metaspace)则是和 Java 堆(Heap)等其他区域平级的,更加灵活。
9、Java对象的定位方式
句柄池、直接指针。
10、什么是句柄池,简单总结一下
句柄池是Java虚拟机(JVM)中用于存储对象句柄(Object Handle)的数据结构。它由对象引用和句柄描述符两部分组成,其中对象引用存储在句柄池中,句柄描述符用于定位实际的对象存储位置。句柄池的作用是解决对象可移植性问题,可以提高Java程序的可移植性,并减少垃圾回收器的负担。
11、jvm 元空间扩容满了,会垃圾回收吗
JVM 的永久代(PermGen)在 Java 8 及以后版本已被移除,取而代之的是元空间(Metaspace)。而元空间是没有固定大小限制的,它的大小是由系统内存来动态分配的。
当元空间满了,会触发元空间的扩容。元空间的扩容方式可以是自动扩容,也可以是手动调整。自动扩容通过调整 -XX:MetaspaceSize
和-XX:MaxMetaspaceSize
参数来实现,当元空间的使用量接近上限时,JVM 会自动进行扩容。手动调整则需要通过 -XX:MetaspaceSize
参数来设置元空间的初始大小以及使用 -XX:MaxMetaspaceFreeRatio
和-XX:MinMetaspaceFreeRatio
参数来指定元空间的增长幅度和扩容策略。
注意:无论是自动扩容还是手动调整,元空间不会直接触发垃圾回收。
- 在进行元空间扩容时,JVM 会先尝试释放永远无法被回收的类加载器、类、字符串等资源(例如被引用着的类对象无法被回收),如果释放后仍然不够空间,就会抛出 OOM(Out Of Memory)异常。
- 因此,元空间虽然不直接进行垃圾回收,但在扩容过程中会尽可能释放无法被回收的资源。同时,也需要合理设置元空间的大小和扩容策略,以避免出现 OOM 异常。
网友评论