今天看了下之前做的一个异步处理任务的服务,发现占用内存量比较大,达到2G,但我检查了代码,基本没有static对象。但这个服务有个特点,就是每次执行一个任务的时候,会从数据库中捞大量的数据做处理,因此我怀疑是因为有比较多的临时对象产生,但程序没有来的及释放。为了验证这个,我用了jinfo查看和临时设置启动参数,jmap查看内存占用情况和主动触发FGC,jstat查看gc情况,top查看整个程序占用的内存量。

用jmap查看,发现内存占用并没有那么高(free值很大),但capacity比较大。用top查看,整个程序也占用了接近2G,那既然free那么多,为啥程序还占用那么高的内存?是不是因为还没有gc导致?

因此我用jmap做了一次主动gc:

/opt/jdk/bin/jmap -histo:live PID

,看了top,还是一样大小,只是jmap出来的free值更高了(特别是老年代,新生代的used变成了0),说明gc是有起到作用的。但是,为啥top没有变化??

后来查了jmap出来的参数,MaxHeapFreeRatio参数的意思是,当空闲内存数超出这个值时,会回收内存直到最小内存。而我的程序里面,默认这个值是100,也就是说要所有内存都未使用才会释放(都100%未使用了还需要释放吗?没鸟用了)。为了验证,我用jinfo临时设置了参数:

/opt/jdk/bin/jinfo -flag MaxHeapFreeRatio=70 PID

,主动触发gc,发现top内存降到了1G。问题解决了。

网上有人遇到top出来的res结果和jmap查出来的结果不一致,具体原因我也没搞懂,但是,只要触发了gc,而且内存做了回收,结果应该跟top出来的结果是一致的。

但jinfo只是临时设置,为了程序每次启动都生效,必须在启动脚本中设置。这个是在gradle中。我的服务有个build.gradle文件,在里面加几个参数:

defaultJvmOpts = ["-XX:MaxHeapFreeRatio=70", "-XX:MaxTenuringThreshold=3", "-XX:MaxNewSize=1073741824"]
MaxTenuringThreshold代表对象的被回收存活次数,
MaxNewSize代表新生代内存大小。

执行build后自动生成启动脚本,搞定!

相关链接:
1、jvm启动参数
2、jstat使用
3、各种java工具
4、打印当前java的所有参数
5、jinfo设置参数
6、别人的例子(仅做参考)

JVM调参的更多相关文章

  1. Java基础-JVM调优策略简介

    Java基础-JVM调优策略简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JVM结构分析 1>.JVM结构图 2>.JVM运行时数据区功能说明 JVM管理的内 ...

  2. JVM调优(三)——基于Btrace的监控调试

    JVM调优(三)--基于Btrace的监控调试 简介 Btrace可以动态地向目标应用程序的字节码注入追踪代码 用到的技术: JavaComplierApi.JVMTI.Agent.Instrumen ...

  3. JVM调优基础到进阶

    GC和GC Tuning GC的基础知识 1.什么是垃圾 C语言申请内存:malloc free C++: new delete c/C++ 手动回收内存 Java: new ? 自动内存回收,编程上 ...

  4. JVM调优工具锦囊

    Arthas线上 分析诊断调优工具 以前我们要排查线上问题,通常使用的是jdk自带的调优工具和命令.最常见的就是dump线上日志,然后下载到本地,导入到jvisualvm工具中.这样操作有诸多不变,现 ...

  5. scikit-learn随机森林调参小结

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...

  6. scikit-learn 梯度提升树(GBDT)调参小结

    在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...

  7. jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎 ...

  8. jvm系列(六):jvm调优-从eclipse开始

    jvm调优-从eclipse开始 概述 什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配.回收的情况来调整各区域内存比例或者gc回收的策略:更深一层就是根据dump出来的内存结构和线程 ...

  9. word2vec参数调整 及lda调参

     一.word2vec调参   ./word2vec -train resultbig.txt -output vectors.bin -cbow 0 -size 200 -window 5 -neg ...

随机推荐

  1. 内网穿透—使用 frp 实现内外网互通

    前言 什么是内网穿透? 内网穿透,又叫 NET 穿透,是计算机用语.用通俗的说法就是你家里的个人电脑,可以直接被外网的人访问.例如你在公司,不通过远程工具,直接也可以访问到家里的电脑(本文章特指 we ...

  2. pymongdb入门

    Pymongo入门 安装 pip install pymongo 连接 实际就是实例化一个客户端对象,然后客户端对象中指定一个库作为库对象,库对象中的集合对象就是之后常用来执行操作的对象 1 ''' ...

  3. ceph对象存储场景

    安装ceph-radosgw [root@ceph-node1 ~]# cd /etc/ceph # 这里要注意ceph的源,要和之前安装的ceph集群同一个版本 [root@ceph-node1 c ...

  4. 什么是 IP 地址 – 定义和解释

    IP 地址定义 IP 地址是一个唯一地址,用于标识互联网或本地网络上的设备.IP 代表"互联网协议",它是控制通过互联网或本地网络发送的数据格式的一组规则. 本质上,IP 地址是允 ...

  5. ORACLE中dual用法详解

    基本上oracle引入dual为的就是符合语法1. 我们先从名称来说,dual不是缩写词,本身就是完整的单词.dual名词意思是对数,做形容词时是指二重的,二元的.2. Oracle中的dual表是一 ...

  6. [项目总结]论Android Adapter notifyDataSetChanged与notifyDataSetInvalidated无效原因

    最近在开发中遇到一个问题,Adapter中使用notifyDataSetChanged 与notifyDataSetInvalidated无效,经过思考和网上查找,得出如下原因. 首先看一下notif ...

  7. mybatis中返回自动生成的id

    当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢. 在mysql数据中我们可以在insert下添加一个selectKey用以指定返回的类型和值:     ...

  8. 【Java 8】Predicate详解

    一.java.util.function.Predicate 这里类是java自带主要广泛用在支持lambda表达式的API中. 1.接口源码 @FunctionalInterface public ...

  9. ubuntu 使用mysql

    一: 安装: sudo apt-get install mysql-serversudo apt-get install mysql-clientsudo apt-get install libmys ...

  10. 「Spark从精通到重新入门(二)」Spark中不可不知的动态资源分配

    前言 资源是影响 Spark 应用执行效率的一个重要因素.Spark 应用中真正执行 task 的组件是 Executor,可以通过spark.executor.instances 指定 Spark ...