文章目录
一切不仅仅为了面试
提示:仅仅代表个人理解
JVM调优理解
JVM调优是指调整和配置JVM的参数以优化运行Java应用程序的性能,主要目标是提高应用的响应速度和提高应用的吞吐量 、减少延迟以及确保资源高效使用 。调优通常针对内存管理 、垃圾收集策略 、线程堆栈大小等方面进行。
JVM调什么:
提示:这里我就想吐槽一下:不要没病乱吃药,同样JVM没啥问题不要乱调
分析应用的性能特征:首先需要使用诊断工具(如jConsole、VisualVM、JProfiler等)收集Java应用的运行时数据。
确定调优目标:了解应用的需求,是否关注高吞吐量、低延迟还是内存使用效率等。
选择合适的垃圾收集器:基于应用需求选择合适的垃圾收集器,如CMS、G1、ZGC等。
调整内存分配:分析并设置适当的堆内存大小、新生代和老年代的比例、元空间大小等。
调整性能参数 :例如调整JIT编译器行为、线程堆栈的大小等。
(JIT是"Just-In-Time"编译器的缩写,它是一种运行时编译器)
持续测试和监控:在调整参数后,需要持续测试应用并监控其性能,以确保调优取得预期效果。
怎么调:
1、堆内存设置(比如-Xms和-Xmx参数设置初始和最大堆内存)。
2、新生代和老年代的大小比例(使用-XX:NewRatio)。
3、垃圾收集器选择和调整
(比如-XX:+UseG1GC,-XX:+UseConcMarkSweepGC)。
4、垃圾收集细节调整
(如设置线程数量-XX:ConcGCThreads,年轻代大小-XX:NewSize等)。
5、JVM堆栈大小(如-Xss设置每个线程的堆栈大小)。
6、逃逸分析和内联优化(如-XX:+DoEscapeAnalysis启用逃逸分析优化)。
为了解决什么问题:
1、减少垃圾收集的频率和暂停时间,避免影响到用户体验。
2、防止内存泄漏和内存溢出。
3、提高吞吐量,确保程序可以在短时间内处理更多的工作负载。
4、控制资源消耗,防止应用消耗过多的系统资源。
正常情况下需要调吗:
在许多情况下,JVM默认参数可以适用于标准应用程序,不需要特别的调优。
但对于有特定性能目标或在资源使用上有特定限制的重要应用程序,JVM调优是必要的。
例如,对于大规模的、内存密集型的或者要求高实时性的应用程序,经过专业调优后通常会有显著的性能改进。
总之,JVM调优是一个持续的过程,需要基于实际运行数据不断优化。快速反应的监控和分析,以及在实际运行环境中测试和验证调优效果非常重要。
JVM垃圾收集器
提示:思想,仅仅是思想
区分垃圾
在JVM中垃圾回收的第一步是确认什么是垃圾,现代主流的JVM实现主要使用可达性分析 算法来识别哪些对象是垃圾。引用计数法 因为循环引用等问题在Java虚拟机中并未广泛采用。
收集方式
垃圾收集的区域划分:
1、新生代(Young Generation)收集 :收集新创建的对象,这些对象大多是短命的。
2、老年代(Old Generation/Tenured Space)收集 :收集长时间存活的对象。
3、永久代(PermGen) :在Java 8之前的版本中,存放类信息和常量。Java 8及之后,被**元空间(Metaspace)**所取代。
4、全部空间收集:也称为Full GC,会涉及新生代、老年代以及元空间(如果使用的是Java 8+版本)的收集。
按照收集垃圾的线程数量划分:
单线程收集 :使用单个线程执行垃圾回收,这可能会导致较长的暂停时间,主要见于旧式或者简单的垃圾收集器中。
多线程收集:使用多个线程并发执行垃圾回收,以减少暂停时间和提高垃圾回收效率,现代垃圾收集器通常采用多线程。
对空间的利用率划分:
标记-清除 (Mark-Sweep):标记所有可达对象,然后清除未被标记的对象,这种方法会产生内存碎片。
标记-整理 (Mark-Compact):标记所有可达对象,然后将活动对象移向内存的一端,清理掉未被移动的部分,这种方法减少了内存碎片。
复制(Copying):将内存分为两块,每次只使用一块。垃圾收集时,将活动对象复制到未被使用的另一块内存区域,然后清除原有的那块内存区域中所有对象。
具体的垃圾收集器 :每种垃圾收集器的实现通常采用多种上述策略的组合,针对不同的场景和需求进行优化,如:
1、Serial Collector:一个单线程收集器,适用于小型堆。
2、Parallel Collector:一个多线程收集器,也被称作"Throughput Collector",适用于中到大型堆。
3、CMS (Concurrent Mark Sweep) Collector:以获取最短回收停顿时间为目标的收集器。
4、G1 (Garbage-First) Collector:适用于大型堆,期望可预测的停顿时间。
5、ZGC (Z Garbage Collector) 和 Shenandoah:为了减少停顿时间到极致而设计的收集器,它们使用了不同的技术实现极低的停顿时间。
垃圾收集器详细介绍:
新生代收集器:
-
Serial收集器:
- 算法:复制算法
- 优点:简单高效,适用于单线程小型应用
- 缺点:停顿时间较长
- 默认区域:新生代
-
ParNew收集器:
- 算法:复制算法
- 优点:多线程并行收集,适用于多核CPU环境
- 缺点:停顿时间较长
- 默认区域:新生代
老年代收集器:
-
Serial Old收集器:
- 算法:标记-整理算法
- 优点:简单高效,适用于单线程小型应用
- 缺点:停顿时间较长
- 默认区域:老年代
-
Parallel Old收集器:
- 算法:标记-整理算法
- 优点:多线程并行收集,适用于多核CPU环境
- 缺点:停顿时间较长
- 默认区域:老年代
整堆收集器:
-
CMS (Concurrent Mark Sweep)收集器:
- 算法:标记-清除算法
- 优点:并发收集,停顿时间短
- 缺点:产生碎片,无法处理浮动垃圾,CPU资源敏感
- 默认区域:老年代
- JDK版本:JDK 1.4至JDK 8
-
G1 (Garbage-First)收集器:
- 算法:分代收集算法,包括复制算法和标记-整理算法
- 优点:整体吞吐量高,可控制停顿时间
- 缺点:运行时开销较大
- 默认区域:整个堆空间
- JDK版本:JDK 9及以后
其他收集器:
-
Shenandoah收集器:
- 算法:并发标记-压缩算法
- 优点:极低的停顿时间,适用于大堆、低延迟的应用
- 缺点:运行时开销较大
- 默认区域:整个堆空间
- JDK版本:JDK 12及以后
-
ZGC (Z Garbage Collector)收集器:
- 算法:并发压缩算法
- 优点:极短的停顿时间,适用于大堆、低延迟的应用
- 缺点:运行时开销较大
- 默认区域:整个堆空间
- JDK版本:JDK 11及以后
小结
提示:未完成
这个文章其实并未完成,这里还有一些关于JVM中的数据怎么去可视化,怎么去分析数据性能,异常之后怎么去操作如:OOM之后等等
后续会补上。并在完善当前文章