0
点赞
收藏
分享

微信扫一扫

Sqli-labs-master第一关通关攻略

JVM/GC


已更新完—有需要补充的请留言,大家一起学习

JVM(java虚拟机)

参数类型实例解释说明
标准参数-help很稳定,占时的JVM版本中都不会进行改变
-X参数(非标准参数)-Xint不稳定,在未来的一些版本中可能会进行一些改变
-XX参数(使用率较高)-XX:UseSerialGC再JVM的调优或者JVM的debugger中使用

//-showversion 参数表示先打印版本信息,再去执行后面的命令,再调试的时候非常有用
情况\参数-server-clinet
初始堆空间大一些小一些
默认回收器并行垃圾回收器串行垃圾回收器
启动速度
运行速度
32位操作系统(window)-默认
32位操作系统(其他)2GB以上的内存,2个以上的CPU默认否则选择该模式
64位操作系统不支持
// 进入根目录创建文件
mkdir /test
cd /test/
ll
vim TestJVM.java
//将刚刚的代码复制进去
    public static void main(String[] args) {
        String str = System.getProperty("str");
        if (str == null) {
            System.out.println("this str =null");
        } else {
            System.out.println(str);
        }
    }
//然后编译
javac TestJVM.java
//运行文件
java TestJVM
//设置里面的参数进行运行
java -Dstr=hello TestJVM
//结果如下

在这里插入图片描述

//按照刚刚的方式使用showversion,打印出来的就是显示版本号的基本进信息然后就是this str =null的信息
java -client -showversion TestJVM

java -server-showversion TestJVM

java -X

-X参数作用解释说明
-Xmixed混合模式执行 (默认)价格解释模式和编译迷失进行混合使用,由JVM自己决定,这是jvm的默认模式也是推荐模式
-Xint仅解释模式执行标记会强制JVM执行所有的字节代码,这样就会降低了运行速度,通常是低10倍以上
-Xcomp编译模式和Xint相反,jvm再第一次使用的时候会把所有的字节码编译到本地代码,从而大大的速度上的优化,但是很多应用在使用这个模式的时候都会有一些性能的损失.但是比使用-Xint损失少点,原因是他没有让JIT启动it编译器的全部功能,JIT编译器可以Udine是否需要编译做出判断,如果所有的代码都进行了编译,对于一些只执行一次代码就没有意义了
-Xbootclasspath<用 ; 分隔的目录和 zip/jar 文件>设置搜索路径以引导类和资源
-Xbootclasspath/a<用 ; 分隔的目录和 zip/jar 文件> 附加在引导类路径末尾
-Xbootclasspath/p<用 ; 分隔的目录和 zip/jar 文件>置于引导类路径之前
-Xdiag显示附加诊断消息
-Xnoclassgc禁用类垃圾收集
-Xincgc启用增量垃圾收集
-Xloggc:< file >将 GC 状态记录在文件中 (带时间戳)
-Xbatch禁用后台编译
-Xms< size >设置初始 Java 堆大小
-Xmx< size >设置最大 Java 堆大小
-Xss< size >设置 Java 线程堆栈大小
-Xprof输出 cpu 配置文件数据
-Xfuture启用最严格的检查, 预期将来的默认值
-Xrs减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xcheck:jni对 JNI 函数执行其他检查
-Xshare:off不尝试使用共享类数据
-Xshare:auto在可能的情况下使用共享类数据 (默认)
-Xshare:on要求使用共享类数据, 否则将失败。
-XshowSettings显示所有设置并继续
-XshowSettings:all显示所有设置并继续
-XshowSettings:vm显示所有与 vm 相关的设置并继续
-XshowSettings:properties显示所有属性设置并继续
-XshowSettings:locale显示所有与区域设置相关的设置并继续

-XX参数

类型格式实例
boolean类型-XX:[+ -]< name >表示启用或者禁用< name >属性-XX:DisableExplicitGC表示禁用手动调用GC操作,也就是说System.gc()无效
非boolean类型-XX:< name > =< value >表示< name >属性值为< value >-XX:NewRatio = 1表示新生代和老年代的比值

下面的属于-XX的参数范围

参数解释说明
-Xms设置JVM的堆内存初始大小
-Xmx设置JVM的堆内存最大大小
//比如运行下面的程序实例
java -Xms512m -Xmx2048m TestJVM

什么时候需要查看JVM的运行参数

jvm的内存模型
1.7版本
在这里插入图片描述
1.8版本
在这里插入图片描述在这里插入图片描述
可以看出1.8版本的组成为:年轻代 + 老年代
年轻代: Eden + 2个Survivor
老年代:OldGen
元数据空间:所占用的内存空间不是再虚拟机内部的,而是再本地内存空间中
在这里插入图片描述通过jstat命令进行查看堆内存的使用情况

参数解释说明
Loaded加载class的数量
Bytes所占用的空间大小
Unloaded未加载数量
Bytes未加载占用的空间
Time总时间
参数解释说明
Compiled编译的数量
Failed失败数量
Invalid不可用数量
Time总时间
FailedType失败类型
FailedMethod失败的方法
参数解释说明
S0C第一个Survivor区的大小
S1C第二个Survivor区的大小
S0U第一个Survivor区的使用大小
S1U第二个Survivor区的使用大小
EUEden区的大小
ECEden区的使用大小
OCOld区的大小
OUOld区的使用大小
MC方法区大小
MU方法区使用大小
CCSC压缩类空间大小
CCSU压缩类空间使用大小
YGC年轻代垃圾回收次数
YGCT年轻代垃圾回收耗时时间
FGC老年代垃圾回收次数
FGCT老年代垃圾回收耗时时间
GCT垃圾回收耗时总时长
对象说明
BBYTE
CCHAR
DDOUBLE
FFLOAT
IINT
JLONG
ZBOOLEAN
[数组例如:[I表示的就是int[]
[L+类名其他对象

MAT

在这里插入图片描述打开文件
在这里插入图片描述
在这里插入图片描述选择之前的dump的文件
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

jstack(将正在运行的JVM的线程进行快照并且打印出来)

状态解释说明
初始状态(NEW)创建一个Thread对象,但是还没有调用start()启动线程时,线程处于初始状态
运行状态(Runnable)再java中,运行状态包括就绪状态和运行状态
运行状态(就绪状态)这个状态下的线程已经获取到了所要执行的资源,只需要分配CPU执行权即可执行,所有的就绪状态的线程都是存放在就绪队列中的
运行状态(运行状态)获取到CPU的执行权,正在执行线程,由于一个cpu同一时刻只能执行一个线程,所以每一个cpu每个时刻只有一条运行状态的线程
阻塞状态(Blocked)当每一个正在执行的线程请求某一条资源失败的时候就会进入阻塞状态,在java中阻塞状态专指请求锁失败时进入的状态,由于一个阻塞队列存放所有的阻塞状态的线程,处于阻塞状态的线程会不断的请求资源,一旦请求成功,就会进入就绪状态等待执行
等待状态(Waiting)当前线程中调用wait,join,park函数的时候,当前线程就会进入等待状态,也有一个等待的队列存放在所有的等待状态的线程;线程处于等待状态表示需要等待其他的线程的指示才能继续运行;进入等待状态的线程会释放CPU的执行权,并且释放资源(如:锁)
超时等待状态(Timed_Waiting)-当运行的线程调用sleep(time),wait,join,parkNanos,parkUntil的时候,就会进入到这个状态; 他和等待状态一样,并不是因为请求不到资源,而是主动的进入,并且进入后需要其他线程的唤醒;进入这个状态后释放CPU执行权和占有的资源; 与等待状态的区别就是,到了超时时间以后自动进入阻塞队列,开始竞争锁
终止状态(Terminated)线程执行结束后的状态

死锁

VisualVM工具(监控线程内存使用情况)

在这里插入图片描述

VisualVM命令

  • 内存信息
  • 线程信息
  • Dump堆(本地进程)
  • Dump线程(本地进程)
  • 打开对Dump,堆Dump可以用jmap来生成
  • 打开线程Dump
  • 生成应用快照(包含内存信息,线程信息等等)
  • 性能分析,CPU分析(各个方法调用时间,检查那些方法耗时长),内存分析(各类对象占用的内存,检查那些类占用的内存多)

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述监控远程的JVM

JMX

在这里插入图片描述在这里插入图片描述

分析堆日志

"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f8e04001800 nid=0x5103 waiting on condition [0x000070000e2ef000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.example.MyApp.processData(MyApp.java:45)
        at com.example.MyApp.run(MyApp.java:23)
        at java.lang.Thread.run(Thread.java:748)

"Thread-2" #13 prio=5 os_prio=0 tid=0x00007f8e04002000 nid=0x5203 waiting on condition [0x000070000e3f2000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at com.example.MyApp.processData(MyApp.java:45)
        at com.example.MyApp.run(MyApp.java:23)
        at java.lang.Thread.run(Thread.java:748)

"Thread-3" #14 prio=5 os_prio=0 tid=0x00007f8e04002800 nid=0x5303 waiting on condition [0x000070000e4f5000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076af8aeb8> (a java.util.concurrent.CountDownLatch$Sync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:

997)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
        at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
        at com.example.MyApp.processData(MyApp.java:60)
        at com.example.MyApp.run(MyApp.java:23)
        at java.lang.Thread.run(Thread.java:748)

什么情况下可能需要JVM调优

  • 堆内存持续增长:如果应用程序的堆内存持续增长并且接近或达到了最大内存限制(由 -Xmx 参数设置),这可能表明存在内存泄漏或者内存使用不合理的情况,需要进行调优来优化内存使用。
  • 频繁的Full GC:如果应用程序中频繁发生Full GC,即对整个堆进行回收的情况,这可能会导致较长的停顿时间和性能下降。调优的目标是尽量减少Full GC的次数。
  • 垃圾回收停顿时间过长:如果垃圾回收的停顿时间超过了可接受的范围(一般认为超过1秒),可能会影响应用程序的响应性能和用户体验。调优的目标是减小垃圾回收的停顿时间。
  • 内存异常:如果应用程序经常遇到内存异常,如OutOfMemoryError,表明应用程序的内存使用超出了JVM的限制,需要调优来提高内存的利用率和稳定性。
  • 大量占用内存的本地缓存:如果应用程序中使用了大量的本地缓存,并且占用了大量的内存空间,可能会导致内存不足的问题。调优的目标是优化缓存策略和内存管理,减少内存占用。
  • 性能不佳或不稳定:如果应用程序的吞吐量和响应性能不高或不稳定,可能是由于内存管理不当导致的。调优的目标是提高应用程序的性能和稳定性。
  • 除了命令行参数外,可以在应用程序代码使用System.setProperty()方法来动态设置JVM参数如:
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "8");

补充JVM内部结构

在这里插入图片描述

JVM 调优策略(补充)

GC

垃圾回收算法

1.引用计数法

循环引用
A a = new A();
B b = new B();
a.b=b;
b.a=a;
a=null;
b=null;

2.标记清除发

3.标记压缩算法

4.复制算法

5.分代算法

算法优点缺点说明
引用计数法1.实用性较高,无需等到内存不够的时候,才可以进行回收,运行的时候根据对象的计数器是否为0,就可以直接进行回收了 2.在垃圾回收的过程中,引用无需挂起,如果申请内存的时候内存不足,则会立即outofmenber错误 3.区域性,更新对象的计数器的时候,只是影响到该对象,不会扫描全部的对象1.对象每次被引用的时候,都需要去更新计数器,有一定时间的开销2.浪费cpu资源,即使是内存足够的情况下,任然运行时进行着计数器的统计 3.无法解决循环引用的问题(最大的缺点)假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用失败的时候,对象A的引用计数器就-1,如果对象A的计数器值为0,就是说明A没有被引用,可以被回收了
标记清除算法1.解决了循环引用的问题1.效率比较低,标记和清除2个动作都是需要遍历所有的对象,并且再GC的时候需要暂停应用程序,对于交互性要求高的应用而言这个体验是非常差的 2.通过标记清除的算法清理出来的内存,碎片化比较严重,因为被回收的对象可能存在于内存的各个角落,所以清理出来内存是不连贯的是将垃圾护手分为2个阶段,分别为标记和清除1.标记:从根节点开始标记引用的对象2.清除:未被标记引用的对象就是垃圾回收对象,可以被清理;暂停程序线程,没有被标记的对象会被回收清除掉然后被标记的对象留下来并进行重置变为未标记的状态,恢复程序线程,程序继续运行
标记压缩算法解决了标记清除法里面而定碎片化问题标记压缩算法多了一个压缩的步骤,这样就会导致其中的清除的整体效率受到了影响再标记清除算法的基础之上做的优化,和标记清除算法一样,也是从根节点开始,对对象的应用进行标记,在清理的阶段,并不是简单地清理未标记的对象,而是将存货的对象压缩到哦内存的一段,然后清理边界意外的垃圾,从而解决碎片化的问题
复制算法1.在垃圾对象多的情况下,效率高 2.清理以后,内存无碎片1.再垃圾对象少的时候不适合 2.分配的2块内存空间,再同一时刻只能使用一半,内存使用率较低将原有的内存空间一分为二,每次只用到其中的一块,在垃圾回收的时候,将正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换内存的角色,完成垃圾回收
分代算法分代算法指的是根据回收对象的特点进行选择,再jvm中,年轻代适合复制算法,老年代适合标记清除或者标记压缩算法

收集器

参数说明
-XX:UseSerialGC指定的年轻代和老年代都使用串行垃圾收集器
-XX:+PrintGCDetails打印垃圾回收的详细信息
-XX:UseParallelGC年轻代使用ParallelGC垃圾回收期,老年代使用串行回收器
-XX:UseParallelOldGC年轻代使用ParallelGC垃圾回收期,老年代使用ParallelOld垃圾回收器
-XX:MaxGCPauseMillis(设置最大的垃圾收集时候的停顿时间,单位毫秒,需要注意的是ParallelGC为了达到设置的停顿时间,可能会调整堆的大小或者其他的参数,如果堆的大小设置的比较小,就会导致GC工作变得很频繁,反而可能会影响到性能,这个参数使用的时候需要谨慎处理)
-XX:GCTimeRatio(设置垃圾回收时间占程序运行时间的百分比,公式:1/(1+n),他的值为0~100之间的数字,默认值为99,也就是垃圾回收事假不能超过1%)
-XX:UseAdaptiveSizePolicy(自适应GC模式,垃圾回收器将会自动的调整新生代,老年代等参数,达到吞吐量,堆大小,停顿时间之间的平衡;一般用于手动的调整比较困难的场景,让收集器自动的进行调整)
-XX:+UseG1GC使用G1垃圾收集器
-XX:+MaxGCPauseMillis设置期望达到的最大GC停顿时间指标,默认是200毫秒,但是jvm不一定能保证达到这个指标
-XX:+ParallelGCthreads=n设置STW工作线程数的值,将n的值设置为逻辑处理器的值.n的值与逻辑处理器的数量相同,最多为8
-XX:+ConcGCThreads=n设置并行标记的线程数,将n设置为并行垃圾回收线程数的1/4左右
-XX:+G1HeapRegionSize设置的G1区域的大小,值是2的幂,范围是1mb~32mb之间,目标是根据最小dejava堆大小划分为≈2048个区域, 默认是堆内存的1/2000
-XX:+InitiatingHeapOccupancyPercent=n设置处罚标记周期的java堆占用率阀值,默认占用率是整个java堆的45%

在这里插入图片描述

参数解读冒号后面的内容解释
DefNew表示使用的是串行垃圾收集器4416K->512K(4928K)====>表示年轻代GC占用的内存是4416K内存,GC之后占用512K内存总大小4928K;0.0046102 secs =====>表示的是GC所用的时间单位毫秒 ;
-XX:+PrintGCDetails打印垃圾回收的详细信息

1.串行垃圾收集器

//设置堆的初始和最大内存值为16M  串行收集器
-XX:+UseSerialGC -XX:+PrintGCDetails -Xms16m -Xmx16m

2.并行垃圾收集器

在这里插入图片描述

2.CMS垃圾收集器

3.G1垃圾收集器(重点)jdk1.7开始1.9默认的回收器

Young GC模式

在这里插入图片描述

Mixed GC

可视化的GC日志分析工具

举报

相关推荐

0 条评论