当前位置: 首页 > news >正文

【JVM】实战篇(一)

【JVM】实战篇(一)

  • 1. 实战篇内容介绍
  • 2. 内存调优
    • 2.1 内存溢出(OutOfMemory)和内存泄漏(memory leak)
      • 2.1.1 内存泄露的demo
  • 3. 解决内存溢出
    • 3.1 top命令
    • 3.2 VisualVM
  • 附录

1. 实战篇内容介绍

实战篇从三方面利用Java虚拟机进行生产环境线上问题解决以及性能问题的优化。

在这里插入图片描述

2. 内存调优

2.1 内存溢出(OutOfMemory)和内存泄漏(memory leak)

  • 内存泄露(memory leak) :在Java中如果不再使用一个对象,但是该对象依然在GC ROOT的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内存泄漏
  • 内存泄漏绝大多数情况下都是由堆内存泄露引起的。
  • 少量的内存泄露可以容忍,但是如果发生持续的内存泄露,不管有多大的内存都会被消耗完,最终导致内存溢出(OutOfMemory)。但是产生的内存溢出不只有内存泄漏这一个原因。

2.1.1 内存泄露的demo

在这里插入图片描述

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

在这里插入图片描述

  • 内存泄露导致溢出的常见场景是大型的Java后端应用中,在处理用户请求后,没有及时将用户的数据删除。随着用户请求数量越来越多,内存泄漏的对象占满了堆内存最终导致内存溢出。
  • 第二种常见的是分布式任务调用系统,比如Elastic-job、Quartz等进行任务调度时,被调度的Java应用在调度任务结束中出现了内存泄露,最终导致多次调度后内存溢出。这种重启之后也可以回复使用,但是过段时间之后还是会内存溢出。

3. 解决内存溢出

解决内存溢出的步骤总共分为四个步骤,其中前两个步骤最为核心:
在这里插入图片描述

3.1 top命令

  • top命令是Linux下用来查看系统信息的一个命令,它提供给我们去实时的查看系统的资源,比如执行时的进程、线程和系统参数等信息。
  • 进程使用的内存为RES(常驻内存) SHR(共享内存)

在这里插入图片描述

top - 17:45:57 up 59 days,  1:38,  3 users,  load average: 0.27, 0.33, 0.32
Tasks: 233 total,   1 running, 232 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.8 us,  0.8 sy,  0.0 ni, 96.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 32941696 total,   358424 free, 13474308 used, 19108964 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 17314436 avail Mem PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
10482 3000      20   0 7252020   1.2g  56004 S  10.3  4.0   7720:20 java                                                  
26588 root      20   0   13.9g   2.4g  22888 S   9.0  7.6   6400:26 java                                                  1625 root      20   0  461252 107768      4 S   3.0  0.3 211:20.90 scanner_clamav                                        
19239 1000      20   0   21.7g 604880  30152 S   2.0  1.8   2695:05 node                                                  2123 root      20   0 2071528  43008  16456 S   0.7  0.1 159:11.21 containerd                                            3361 polkitd   20   0 5042896 787592  22072 S   0.7  2.4 663:06.44 mysqld                                                
10055 root      20   0 7949416   1.6g  20368 S   0.7  5.1 496:05.35 java                                                  9 root      20   0       0      0      0 S   0.3  0.0  48:40.62 rcu_sched                                             1462 root      20   0 1464604  57188   7136 S   0.3  0.2 226:27.61 proxima                                               1543 root      20   0 1492708  31896   7480 S   0.3  0.1  98:09.50 collector                                             1602 root      20   0   28228   9504    696 S   0.3  0.0  81:59.17 driver                                                2662 root      20   0 3525588 126092  31328 S   0.3  0.4 200:42.35 dockerd                                               3362 root      20   0  138864  12812   5344 S   0.3  0.0 261:14.95 redis-server                                          5170 root      20   0 3254180   1.1g  17832 S   0.3  3.3 516:11.54 java                                                  
10151 3000      20   0 6827048 642972  18236 S   0.3  2.0 282:44.42 java                                                  
18566 1000      20   0 6623724   1.2g  17084 S   0.3  3.9 779:59.83 java                                                  
22487 root      20   0 1236448   9432   4556 S   0.3  0.0   3:58.98 containerd-shim                                       
31925 root      20   0    9.8g 386188  16092 S   0.3  1.2 306:14.33 java                                                  1 root      20   0  191304   4328   2648 S   0.0  0.0  42:32.37 systemd                                               2 root      20   0       0      0      0 S   0.0  0.0   0:00.05 kthreadd                
字段含义
17:45:57当前系统时间
up 59 days, 1:38系统已运行 59 天 1 小时 38 分钟(自上次重启以来)
3 users当前登录的用户数(可以用 who 命令查看)
load average: 0.27, 0.33, 0.32系统平均负载(1 分钟、5 分钟、15 分钟平均运行队列长度)
  • “平均负载” 是 CPU 正在处理 + 等待处理的任务数。
  • 如果平均负载 ≈ CPU 核心数,表示负载饱和。
    例如:4 核 CPU → 平均负载 > 4 说明 CPU 忙不过来了。
字段含义
233 total总共有 233 个任务(进程)
1 running当前正在运行(占用 CPU)的进程数量
232 sleeping休眠中的进程(等待事件,如 I/O、网络、锁等)
0 stopped暂停的进程(被信号停止)
0 zombie僵尸进程(父进程未回收的子进程)

%Cpu(s):  2.8 us,  0.8 sy,  0.0 ni, 96.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
字段含义
us (user)用户空间占用 CPU 百分比(普通应用程序)
sy (system)内核空间占用 CPU 百分比(系统调用、驱动等)
ni (nice)通过 nice 调整优先级的进程占用 CPU 百分比
id (idle)CPU 空闲时间百分比
wa (wait)等待 I/O(磁盘、网络等)所花费的时间百分比
hi (hardware irq)硬中断占用 CPU 百分比
si (software irq)软中断占用 CPU 百分比
st (steal)被虚拟化环境(如云主机)“偷走”的 CPU 时间百分比(宿主机忙)

📘 解释:

  • 这里 96.4% id 表示 CPU 基本空闲。
  • 如果 wa 高 → I/O 瓶颈。
  • 如果 sy 高 → 系统调用或内核开销大。
  • 如果 st 高 → 云服务器 CPU 被宿主机抢占。

内存使用情况

KiB Mem : 32941696 total,   358424 free, 13474308 used, 19108964 buff/cache
字段含义
total物理内存总量(约 32GB)
free完全未被使用的内存(仅 350MB 左右)
used已被程序占用的内存
buff/cache被缓存或缓冲区使用的内存(Linux 会尽量用空闲内存做缓存,加速文件访问)

交换分区(Swap)

KiB Swap:        0 total,        0 free,        0 used. 17314436 avail Mem
字段含义
total/free/usedSwap 分区的总量、空闲、已使用情况
avail Mem应用程序实际可用的内存(包含 cache 可回收部分)

📘 解释:

  • 系统当前 没有启用 Swap(total=0),所以全靠物理内存;
  • 若内存不足且无 Swap,会更容易触发 OutOfMemory。

进程详细列表

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
列名含义
PID进程 ID
USER进程所属用户
PR优先级(priority,数值越小优先级越高)
NInice 值(进程优先级修正值,负数优先级更高)
VIRT进程使用的虚拟内存总量(包含共享库、缓存、Swap 映射等)
RES实际占用的物理内存(Resident Set Size)
SHR共享内存(与其他进程共享的部分)
S进程状态:
  • R = running(运行中)
  • S = sleeping(休眠)
  • T = stopped(停止)
  • Z = zombie(僵尸)

| %CPU | 进程占用的 CPU 百分比 |
| %MEM | 进程占用的内存百分比(相对物理内存总量) |
| TIME+ | 进程累计占用 CPU 的总时间(用户+系统) |
| COMMAND | 启动该进程的命令名 |

举例

PID   USER PR  NI    VIRT    RES    SHR   S  %CPU   %MEM     TIME+     COMMAND    
10482 3000 20 0    7252020  1.2g   56004  S  10.3   4.0      7720:20     java

含义:

  • PID = 10482
  • 属于用户 3000
  • 优先级 20
  • 占用物理内存 1.2GB(占总内存 4%)
  • 虚拟内存 7.25GB(包含 JVM 映射空间)
  • 当前 CPU 占用 10.3%
  • 运行累计 7720 分钟(约 5.3 天)

free -h命令详解

free -h 是 Linux 上查看内存(RAM)和交换区(swap)使用情况的简单命令,-h 表示以“人类可读”的单位显示(K/M/G 等)。它把内核追踪的几个关键内存指标列出来,帮助判断系统是否缺内存或只是被缓存占用。

[root@iv-ye20h65dz45i3z346rvs opt]# free -htotal        used        free      shared  buff/cache   available
Mem:            31G         12G        424M        1.7G         18G         16G
Swap:            0B          0B          0B
  • total(总物理内存):31G —— 系统检测到的物理内存总量 31 GB
  • used(已用):12G —— 这是按 free 定义的“正在被进程真正占用的内存量(不含 buffer/cache)”
    计算方式(近似、单位换算为 GB):
used ≈ total - free - buff/cache= 31.000G - 0.424G - 18.000G= 12.576G ≈ 显示的 12G(有四舍五入)
  • free(空闲):424M —— 当前完全空着、没有用的物理内存;通常较小,因为 Linux 会把闲置内存用来做缓存。
  • shared(共享):1.7G —— 表示被多个进程共享使用的内存(例如 tmpfs、/dev/shm 或某些共享内存段、容器共享页等)。这个字段在不同内核/工具上的解释略有差别,但一般反映共享映射占用。
  • buff/cache(缓存/缓冲):18G —— 包括 page cache(页面缓存)和 kernel buffers 等,主要用于加速文件/磁盘 I/O。这部分内存是可回收的:当程序需要更多内存时,内核会回收这些缓存来分配给程序,因此它并不等同于“被浪费的内存”。
  • available(可用):16G —— 这是内核估算的“能被新进程或现有进程扩展而无需交换(swap)的内存量”。它比 free 更有参考价值,因为把可回收的缓存考虑进去了。注意这是内核的估算值,不是硬性保证,但比直接看 free 更能反映实际可用内存。
  • 关于差异和四舍五入:
    free 输出是简化和四舍五入后显示的,所以 used + free + buff/cache 不一定精确等于 total(你看到的 12G + 0.424G + 18G ≈ 30.424G,和 31G 有小差异),这是显示精度造成的。
    • Swap 行:0B / 0B / 0B —— 没有配置 swap(既没有交换分区也没有交换文件)。没有 swap 时,一旦内存耗尽,系统会触发 OOM(Out-Of-Memory)杀手结束进程来回收内存;在许多服务器上通常建议至少配置适量 swap(依据需求而定)。

结论
系统有 31GB 物理内存:约 12GB 被进程实际占用,18GB 用作缓存/缓冲(可回收),free 显示只有 424MB 完全空闲,但内核估算 16GB 可立即分配给新进程而不需要 swap。Swap 没有配置(0B),如果担心在内存压力下触发 OOM,可以考虑配置适量 swap。总体来看,当前系统并不是“内存吃紧”的状态——因为大量缓存是可回收的。

3.2 VisualVM

下载地址: https://visualvm.github.io/download.html
在这里插入图片描述

  • VisualVM是多功能合一的Java故障排除工具并且他是一款可视化工具,整合了命令行JDK工具和轻量级分析功能。
  • 这款软件在JDK6~8中发版,在JDK9之后不存在了。
  • 优点:功能封堵,实时监控CPU、内存、线程等详细信息。
  • 支持IDEA插件,开发的过程中也可以使用。
  • 缺点:对于大量集群化部署的Java进程需要手动进行管理。

启动一个Java项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

https://www.bilibili.com/video/BV1r94y1b7eS?spm_id_from=333.788.player.switch&vd_source=240d9002f7c7e3da63cd9a975639409a&p=44

https://www.bilibili.com/video/BV1QJ411P78Q/?spm_id_from=333.337.search-card.all.click&vd_source=240d9002f7c7e3da63cd9a975639409a

附录

  1. 课程地址
http://www.dtcms.com/a/449380.html

相关文章:

  • 住房城市建设部门户网站一件代发48个货源网站
  • 宣武深圳网站建设公司下关网站建设
  • 电商的网站有几个如何做高校的网站版面设计
  • 蚁群算法解决TSP问题
  • 数据库丢失但没备份过?救星:二进制日志
  • 【C++实战(74)】深入C++安全编程:密码学实战之旅
  • inbound 概念及题目
  • UNet改进(43):SaFA-MS-UNet如何提升图像分割精度?
  • 网站建设中的智能元素凡科建站代理商登录
  • Elasticsearch 之分页查询
  • apache hop 不能处理clickhouse 数组格式怎么办?
  • 网站建设 网站设计php语言网站开发公司北京
  • 代码审计
  • 制作网站需要钱吗天津网址
  • cursor使用之没有正常的编辑器中的运行箭头
  • 建设网站优化创意网站建设价格多少
  • soular入门到实战(3) - 如何实现TikLab工具链统一登录认证
  • Python图形界面——海龟绘图
  • 《强化学习数学原理》学习笔记9——值迭代算法
  • 网站建设 统一标准体系什么是网络销售
  • 网站开发语言有哪几种临沂专业网站制作
  • 花店网站建设方案网站木马文件删除
  • Bash 的基本语法总结
  • 网站怎么进行优化网站开发 英文文章
  • 自动驾驶决策规划算法(开幕式)
  • 从零起步学习Redis || 第八章:过期删除策略与内存淘汰策略详解及实战使用(LRU和LFU算法详解)
  • 自动驾驶中的传感器技术65——Navigation(2)
  • 知识体系_scala_利用scala和spark构建数据应用
  • 备案后网站打不开沈阳营销网站建设
  • AI编辑器(FIM补全,AI扩写)简介