JVM解剖

榜样的力量是用来超越的,生死看淡,不服就干

常见的垃圾回收算法

  引用计数

  复制 

  标记清除

  标记整理

 

如何确定垃圾:

  内存中已经不再使用到的空间就是垃圾, 使用计数器,很难解决相互引用的问题

  GC Roots对象作为起点可达性分析,引用可达对象

    哪些可以做为GC roots的对象

      虚拟机栈中引用的对象

      方法区中的类静态属性引用的对象

      方法区中常量引用的对象

      本地方法栈中JNI(native方法)引用的对象

 

查看java进行信息(布尔类型:公式-xx:+或者-某个属性值,kv类型值,jinfo查询运行程序配置):

jinfo -flag PrintGCDetails 39742

jinfo -flag +PrintGCDetails 39742 开启打印

-XX:+PrintGCDetails       +是开启

jinfo -flag MetaspaceSize 39742

jinfo -flag MaxTenuringThreshold 39742   晋升到老年区的匝值

jinfo -flags 39742  所有相关配置信息  默认堆内存是计算机内存的4分之一

 

-Xms 等价于-xx:InitalHeapSize

-Xmx 等价于-xx:MaxHeapSize

java -XX:+PrintFlagsInitial    查看初始值全部参数

java -XX:+PrintFlagsFinal -version    打印的参数中有 :=  表示修改知乎的更新参数值 , =是初始值未修改过  看下修改更新

java -XX:+PrintFlagsFinal -version -XX:MataspaceSize = 512M T   (T表示运行的类名)

java -XX:+PrintCommandLineFlags -version  查看默认垃圾回收器  UseParallelGC,并行gc

 

  ~ jinfo -flag ThreadStackSize 41664

-XX:ThreadStackSize=1024

 

-Xms

  初始大小内存,默认为物理内存的1/64,等价于-xx:InitalHeapSize

-Xmx

  最大分配内存,默认为物理内存的1/4,-xx:MaxHeapSize

-Xss

  设置单个线程栈的大小,一般默认为512k-1024k,等价于-xx:ThreadStackSize

-Xmn

  设置年轻代的大小

-XX:MetaspaceSize: 元空间并不在虚拟机中,而是使用本地内存

 jinfo -flag MetaspaceSize 41664  
-XX:MetaspaceSize=21807104       默认使用21M

 

输出GC详细信息

  名称 GC前内存,GC后内存多少,总的Young GC

-XX:SurvivorRatio     新生代中eden和S0/S1空间的比例, 默认Eden:S0:S1 = 8:1:1  8倍

-XX:NewRatio  配置年轻代和老年代的占比

-XX:MaxTenuringTreshold  进入老年代的匝值最大是15

 

[PSYoungGen: 1972K->504K(2560K)] 1972K->740K(9728K), 0.0156109 secs]

 

https://www.javatang.com/archives/2017/10/25/36441958.html

 

强引用:无法被垃圾回收

软引用:当内存不足才能被回收

弱引用:垃圾回收器执行的时候,如果发现是弱引用就会被回收

虚引用:形同虚设,执行前和执行后是null,当垃圾回收器器,执行的时候,会把虚引用的对象,放入引用队列中,随时可以回收

 

oom

  linux系统默认允许单个进程可以创建的线程是1024个

 

垃圾回收方式

  串行回收(serial):只使用一个线程进行回收,会暂停其他线程操作,stop world

  并行回收(Parallel):多个垃圾收集器并行工作,其他操作也会暂停,stop world

  并发回收(CMS):用户线程和垃圾收集器同时执行,不需要暂停,还是会产生垃圾碎片

  G1回收:不会产生很多内存碎片,stop the world可控,在停顿时间上添加预测机制,用户可以指定期望停顿时间,停顿时间低,改变Eden,Survivor,old 划分独立的小区域,逻辑上的分代隔离,物理上没有区分,增加了大型区域 Humongous,大于G1中region大小50%的对象会存放    

 JVM初始参数:

  java -XX:+PrintCommandLineFlags -version  

  -XX:+UserSerialGC

  jinfo -flag UserSerialGC 6735

 

7个垃圾收集器 ( 划区使用 ):

  Young Gen: Serial Coping, Paralllel Scavenge, ParNew  

  Old Gen: Serial MSC, Parallel Compacting, CMS

  G1收集器不做区域划分

参数说明:

  DefNew: Default New Generation  ...

-XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

  

G1:

  标记过程:

    初始标记,并发标记,最终标记,筛选标记

 

 JVMGC + SpringBoot微服务的生产部署和调参优化

  java -server -Xms1024m -Xmx1024m --XX:UseG1GC -jar xx.war

  Undertow

 

生产环境服务器变慢,诊断思路和性能调优,定位?

   整机

    top 查看cpu和内存   loadaverage 负载压力值 1分钟  15分钟, 查看cpu

    uptime  系统性能精简版

     cpu:

    vmstat -n 2 3   通过两个数字参数来完成,第一个参数是采样的时间间隔数单位是秒,第二个参数是采样的次数

      procs

        r:运行和等待cpu时间片的进程数,原则上1和的cpu的运行队列不要超过2,整个系统的运行队列不能超过总核数的2倍,否则代表系统压力过大

        b:等待资源的进程数,比如正在等待磁盘I/O、网络I/O等

      cpu:

        us:用户进程消耗cpu新能占比

        sy:内核进程消耗cpu的占比

    mpstat -P All 2   查看cpu所有核数

        idle cpu空闲率

    pidstat -u l -p xx  进程占用cpu的使用率

    内存:

    free -m   内存占用超过70%则需要扩容

    pidstat -p 进程号 -r 采样间隔秒数     内存采用频率

   硬盘

    df -h     查看磁盘剩余空间数

  磁盘IO

    iostat -xdk 2 3    await值越小性能越好  

    pidstat -d 采样间隔秒数 -p 进程号

  网络IO

    ifstat 1   每秒一次采样

cpu占用过高排查?

  1.使用top找出进程号

  2.ps -ef | grep java  | grep -v grep,  jps -l

  3.定位代码和线程

     ps -mp 进程id -o THREAD,tid,time             

  4.将需要的线程ID转换为16进制格式小写

    printf "%x\n"   有问题的线程id

  5.jstack  进程id | grep tid(16进制线程的小写)

     

  

 

 

 

 

 

 

  

posted @ 2021-10-19 22:01  外科手术医生  阅读(44)  评论(0编辑  收藏  举报