写在前边

最近公司生产环境的容器云上出了个性能问题,为了做性能分析,使用 JDK 自带的 jmap 收集堆dump,出现了内存溢出导致了容器崩溃。

本篇文章将带你探究,如何规避容器内做堆 dump 导致容器崩溃的问题。适用于低于 Java 8 update 191版本的 JDK。

分析容器崩溃原因

确认容器崩溃的根本原因

毋庸置疑的是容器的内存占用超过了容器的限制,被 k8s 或 docker kill 掉了。

为什么会超过容器的限制呢?

有两种可能:

  • Java 应用服务内存仍在攀升,就算不操作也会崩溃
  • jmap 收集堆dump时占用内存所致

根据容器云平台的运维人员提供的监控截图,基本确认是第二种情况。

Ps: GMT时间+8小时即北京时间,18点左右出现容器内存急剧攀升的情况,而此时正在收集堆dump

为什么 jmap 会申请超过容器限制的内存呢?

首先,我们需要知道 jmap 本身是启动了另一个 JVM 来收集问题应用的 JVM堆的信息的。提到 JVM 运行在容器里会出现的问题,第一个就应该想到 JVM 对容器环境的支持问题,即低于 Java 8 update 191 版本的 JDK 会直接读到物理节点的内存,从而根据物理节点去申请内存,直接导致了容器崩溃。

本次环境就是 OpenJDK 8 低于 191 的版本,所以原因找到了。

解决方案

参考了两个版本的 jmap 官方文档,发现有个可以配置 jmap 所在 JVM 的参数 -Jflag

JDK 7

-J<flag>
Passes <flag> to the Java virtual machine on which jmap is run.

JDK 8

-Jflag
Passes flag to the Java Virtual Machine where the jmap command is running.

这里笔者确认了下这个flag参数最终传递到的是 jmap 所在的 JVM 中,而不是应用服务 JVM

所以方案就比较简单了,根据容器除应用服务 JVM 堆及元空间内存外的可用内存,设置个合理的JVM即可。

示例:容器限制 32G 内存,应用服务堆占用 24G,元空间占用 2G,则可用内存在 6G以下。给容器预留 1G 内存防止其崩溃,可以设置 jmap 使用 5G。

命令格式:jmap [输出dump文件配置] [设置jmap虚拟机参数] [进程号]

jmap -dump:format=b,file=/deployments/heap.hprof -J-Xmx5g 1

参考文档:

https://docs.oracle.com/javase/7/docs/technotes/tools/share/jmap.html

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

本文同步发表在笔者博客园[https://www.cnblogs.com/hellxz/]与CSDN[https://blog.csdn.net/u012586326],禁止转载。

如何规避容器内做Java堆dump导致容器崩溃的问题的更多相关文章

  1. 容器中的Java堆大小调整:快速,轻松

    在上一篇博客中,我们已经看到Java进行了改进,可以根据正在运行的环境(即物理机或容器(码头工人))识别内存.java的最初问题是,它无法弄清楚它是否在容器中运行,并且它曾经为容器运行所在的整个硬件捕 ...

  2. Java:常用的容器小记

    Java:常用的容器小记 对 Java 中的 常用容器,做一个微不足道的小小小小记 容器类概述 常见容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 M ...

  3. 从容器里dump java堆实验探索(原创)

    目标:从docker容器里dump java堆 模拟程序 占用空间500M, 设置启动JVM参数 docker启动命令 (PS:经过测试,至少要650M才能启动容器) 方式1: 通过docker ex ...

  4. 一文深入了解史上最强的Java堆内缓存框架Caffeine

    它提供了一个近乎最佳的命中率.从性能上秒杀其他一堆进程内缓存框架,Spring5更是为了它放弃了使用多年的GuavaCache 缓存,在我们的日常开发中用的非常多,是我们应对各种性能问题支持高并发的一 ...

  5. 性能分析之-- JAVA Thread Dump 分析综述

    性能分析之-- JAVA Thread Dump 分析综述       一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工 ...

  6. 性能监控工具以及java堆分析OOM

      一.性能监控工具 1.系统性能监控 Linux -确定系统运行的整体状态,基本定位问题所在 -uptime: ------系统时间 ------运行时间(例子中为127天) ------连接数(每 ...

  7. Java堆外内存之六:堆外内存溢出问题排查

    一.堆外内存组成 通常JVM的参数我们会配置 -Xms 堆初始内存 -Xmx 堆最大内存 -XX:+UseG1GC/CMS 垃圾回收器 -XX:+DisableExplicitGC 禁止显示GC -X ...

  8. Java堆内存设置

    转自:https://blog.csdn.net/Qiuzhongweiwei/article/details/81023645 堆内存设置 原理 JVM堆内存分为2块:永久空间和堆空间. 永久即持久 ...

  9. MAT工具定位分析Java堆内存泄漏问题方法

    一.MAT概述与安装 MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题.该工具提供了两种使用方式,一种是插件版,可以安装到Eclips ...

随机推荐

  1. LGP7167题解

    考试的一道题,因为某些原因sb了常数翻了好几倍/px 首先我们发现,一个水池的水只会向它下边第一个直径比它大的水池流. 我们把这些流动的关系连边,很容易发现是一棵树. 问水最后会到哪个水池相当于在问最 ...

  2. CTS,CLS,CLR

    1)CTS通用类型系统(Common Type System) CTS不但实现了COM的变量兼容类型,而且还定义了通过用户自定义类型的方式来进行类型扩展.任何以.NET平台作为目标的语言必须建立它的数 ...

  3. Net中委托之一

    1.委托的用法 委托是一种特殊的类型 a. 委托可以类外定义,也可以在类里面定义 b. 委托的操作步骤 1.委托的声明 2.委托的实例化 3.委托的调用 2.委托实例 amespace MyDeleg ...

  4. emu8086 调用LED面板的方法

    一.实验要求 1.熟悉并掌握 EMU8086 汇编语言调试环境: 2.学习 8086 的指令系统,输入简单的指令,观察各寄存器.内存相关单元以及处理器标志位的变化(所有数据传送类指令,可参考教材用例) ...

  5. 互联网前沿技术——01 找不到模块“lodash”

    检查安装 node --version 修改 安装:npm install 启动:grunt server 如果报错: 找不到模块"lodash" https://www.soin ...

  6. 网关中间件-Nginx(二)

    网关中间件-Nginx(一) 第一部分我们主要介绍如下几点: 1.nginx的基本概念 2.nginx结合业务场景实现负载均衡 3.常见问题的举例 这一部分主要介绍Nginx中限流,缓存,动静分离,以 ...

  7. 使用Redis实现关注好友的功能

    现在很多社交都有关注或者添加粉丝的功能, 类似于这样的功能我们如果采用数据库做的话只是单纯得到用户的一些粉丝或者关注列表的话是很简单也很容易实现, 但是如果我想要查出两个甚至多个用户共同关注了哪些人或 ...

  8. java-設計模式-單例模式

    單例模式 一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点. 一个类只有一个实例,且该类能自行创建这个实例的一种模式. 簡單的對比就是: 例如,Windows 中 ...

  9. AutoValue —— Generated immutable value classes

    本文参考 在<Effective Java>第三版第十条"Obey the general contract when overriding equals"中提到goo ...

  10. 【分享】WeX5的正确打开方式(6)——数据组件初探

    本文是[WeX5的正确打开方式]系列的第6篇文章,简单介绍一下WeX5中数据组件的特性和结构形式. 数据组件的由来 上一篇 WeX5绑定机制我们实现了一个简单的记账本应用,当时所有数据都用 JSON ...