惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 司徒正美
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
WordPress大学
WordPress大学
罗磊的独立博客
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
爱范儿
爱范儿
MongoDB | Blog
MongoDB | Blog
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
H
Help Net Security
S
SegmentFault 最新的问题
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
Engineering at Meta
Engineering at Meta
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
D
DataBreaches.Net
雷峰网
雷峰网
GbyAI
GbyAI
宝玉的分享
宝玉的分享

博客园 - BigOrang

在vim中搜索关键字 linux top快捷键 druid 获取数据库连接失败,一直wait.DruidDataSource.takeLast java8类加载器示例&类加载1.8和1.8+的区别 windows查看端口占用 vmware Docker 设置代理 腾讯云域名托管到 cloudflare nginx 代理eureka后css/js/fonts无法访问 docker 基础镜像损坏 一起来找bug茬-01 mysql SHOW PROFILE 将所有容器docker都重启, 但是不重启mysql 正则 .*? 和 .* 的区别是什么 nginx打印所有配置内容 NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder kubesphere org.tmatesoft.svn.core.SVNException: svn: E160013: '/leifengyang/yygh-parent.git' path not found: 404 Not Found (https://gitee.com) 布隆过滤器原理及应用场景 linux中,使用alias, 应该在/etc/bashrc 中写,还是~/.bashrc中写,哪个更好 java date 时间最大连续天数
-Xmx3G -Xms2G 在已经指定了最小内存2G后,启动的时候,就会...
BigOrang · 2025-04-27 · via 博客园 - BigOrang

配置

JAVA_OPTS=" -server -Xmx${Xmx} -Xms${Xms}  -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+C
MSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInit
iatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Dcom.sun.management.jmxremote.port=10001 -Dcom.sun.management.jmxremote.ssl=false

Q: -Xmx3G -Xms2G 在已经指定了最小内存2G后,启动的时候,就会直接分配2G给jvm吗 ?还是动态从1m到2G逐步分配的

在配置中,-Xms2G-Xmx3G 分别指定了 JVM堆内存的初始大小为2GB最大可扩展到3GB

JVM在启动时的行为如下:

  • 由于指定了 -Xms2GJVM在启动时就会直接向操作系统申请并分配2GB的堆内存
  • 不会是从1MB慢慢增长到2GB,而是一开始就分配好2GB。
  • 后续如果堆使用量增长到2GB还不足够,JVM才可能根据需要动态扩展,最多扩展到-Xmx指定的3GB。

总结:

启动时会直接分配2GB堆内存,而不是动态逐步从1MB增长到2GB。


Q:dockerstats 看到的内存占用,为什么是逐步上升的

  • JVM启动时 -Xms=2G,-Xmx=3G
  • docker stats 看到的容器内存使用是逐步上升的,比如 897.1MiB / 31.34GiB

这个现象是正常的,原因如下:

1. 虽然 JVM 启动时向操作系统申请了2GB的堆内存,但不会马上把2GB全部实际使用

  • -Xms2G 会让 JVM 预留 2GB堆空间给对象分配,但:
    • 物理内存(RSS,Resident Set Size)真正占用多少,取决于堆里实际分配的对象数量
    • 如果你的程序在启动时对象很少,虽然堆有2GB的预留空间,但内核只映射实际用到的页面(比如897MB)
    • 其他还没用到的内存页,是惰性分配的,等到程序真正需要(如对象变多)时,内存占用才会上升。

  • docker stats显示的是已经映射到物理内存的实际使用量,不是JVM预留的堆大小。
  • 也就是说,即使你JVM已经预留了2G堆,docker stats上看到的数字,是实际使用了多少内存页面,而不是“申请了多少”。

3. JVM的内存布局不仅仅是堆

  • 除了堆 (Heap) 之外,JVM还有:
    • 线程栈-Xss256k 每个线程的栈大小)
    • 方法区/元空间PermSize, Metaspace
    • JVM自身的代码、C库、GC的数据结构
  • 这些加在一起构成了进程的总体内存,但通常堆内存是最大的部分。
  • 不过由于你主要关注堆,所以堆的行为是最主要影响。

4. 为什么内存占用逐步上升?

  • 程序一开始分配少量对象(占少量堆内存),内存用得少。
  • 运行过程中新建了更多对象,占用的堆逐渐填满,导致物理内存使用上升。
  • 同时,因为你启用了 CMS 回收器(-XX:+UseConcMarkSweepGC),
    • 它是 并发GC,老年代堆如果用得慢,也不会一口气扩展很多。
    • GC策略也影响了物理内存使用的节奏。

5. 至于 146.47% 这种 CPU使用率数字

  • docker stats里 CPU百分比是以 容器CPU配额为基准 计算的。
  • 如果没有限制CPU(默认可以使用宿主机所有核心),
    • 那CPU 100%是指1核跑满,
    • 146.47%意味着1.5核左右的负载,这个跟内存没直接关系。

总结一句话:

JVM确实在启动时预留了2G堆,但物理内存实际分配是按需进行的,所以docker stats里看到的内存使用是逐步上升的,这是JVM和Linux内存管理正常的懒分配(lazy allocation)行为。