Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java进程异常退出

Java进程异常退出

作者头像
用户7886150
修改于 2020-12-15 02:38:03
修改于 2020-12-15 02:38:03
4.1K0
举报
文章被收录于专栏:bit哲学院bit哲学院

参考链接: Java中的异常

今天,内网测试服务器A总是运行一段时间就服务器进程自行退出了,给出了“Java Result :137”这样的错误码。上网查了一下这个137,感觉没有啥有价值的东西。一开始怀疑项目中的JNI调用崩溃到底层,但是没有看到core.*这样的崩溃日志,同时也没有发现OOM的日志,也没有常见的Java 的堆异常log,关键是同样的环境,另外一台机器B,压力远比这个大,都稳定运行很长时间没有问题。下午又崩溃了两三次,一度怀疑Java是不是有什么bug,不过这个想法立马被我否认了,先从自己找原因。 

      晚上,处理完手里的其他事,到家都十一点了,觉得这个崩溃解决不了,就没法睡觉。拿起手机,随意搜了一下“JAVA进程无端退出”,看到了一篇博客提出一个运维神指令dmesg(ps:有时候这个真是救命的神指令)可以查到一个进程的异常信息,在故障诊断方面非常有用。抱着死马当活马医的想法,在出问题的机器敲了一下“dmesg -T | grep java”,看到了“memory cgroup out of memory ,processor kill ....”,这下舒了一口气,JVM进程退出的原因算是知道了,被系统杀掉了,难怪看不到log。 

     不过为什么被杀呢,查了一下cgroup(详情https://blog.csdn.net/huang987246510/article/details/80765628),了解cgroup是Linux提供一种管理系统资源的机制,尤其是控制虚拟机资源或者docker资源有广泛的应用。由于之前知道这个机器A的内存是足够大,为什么内存足够确使用呢。另外一个机器B在同样的JVM虚拟机配置下却可以。通过查询,我发现Docker可以对系统资源进行设置。这里我注意到Docker,猜想这个机器是不是有什么特殊的,这个机器是不是个docker并且限制了内存,但是Java并不能感知到这种限制。想到之前,在通过TOP 观察java进程使用内存,总是徘徊在某个定值附近,大量的内存不被使用,我查了一下docker相关知识,了解到docker通过cgroup机制,实现进程之间诸如CPU,内存,文件系统,网络等资源的隔离,而一些从执行环境收集信息的应用程序已经在 cgroups 存在之前就被执行了。“top”,“free”,“ps”,甚至 JVM 等工具都没有针对在容器内执行高度受限的 Linux 进程进行优化。详情:https://fabiokung.com/2014/03/13/memory-inside-linux-containers/;所以这些收集程序的信息是不准确,只能反映物理机的状况。至此,我假想这个A是个Docker,并且内存做了一定的限制,并且这个限制低于Xmx的设置,从而在运行时,Java堆内存在分配的时候超过了Docker的限制,就触发了cgroup的资源管理机制,在进程组使用的内存达到限额再申请内存,就会触发OOM(out of memory),从而导致进程退出,后来经过和运维同学确认这个机器配置,符合我的猜想,Docker且内存限制8G(低于设置的Xmx12G)。我修改一下Xmx,问题得以解决。 

    上述只是临时解决了问题,有没有更好的办法让Java自己感知到Docker的资源配置呢,比如内存和CPU等。幸运的是,JDK在1.8u131+及java9以后已经考虑这些问题,并且加入了实验性支持参数。具体来说,可以分为两个方面: 

一、CPU限制,即如果没有显式指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount, 那么JVM使用docker的cpu限制。如果docker有指定cpu limit,jvm参数也有指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount,那么以指定的参数为准; 

二、内存限制,通过加上-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap才能使得Xmx感知docker的memory limit;默认情况下,通过java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal可以看到 bool UseCGroupMemoryLimitForHeap = false {experimental} 是关闭的,需要手动打开;打开方式也比较简单,在项目启动参数加上 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap,这样JVM的堆内存将取Xmx和Docker设置的最小值,至此圆满解决问题。 

总结: 

1、在无异常log情况,应用退出,可以先考虑系统中断,dmesg查询相关信息 

2、docker环境会影响应用,使用需要慎重,尤其是开发者和运维人员分离的情况下,开发者应该尽量了解到运维对系统的设置。 

3、JVM的-XX参数需要了解,虽然大部分没有用,但是有些参数对系统优化非常有价值 

下面是官方对Docker支持的文档,不再翻译赘述。 

https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits 

参考文献:https://blog.csdn.net/green1893/article/details/78192017?utm_source=blogxgwz4

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
不得不提的容器 JVM
当我们将 JVM 生态中的关键要素,例如,垃圾收集器、堆大小和运行时编译器设置默认值时,许多技术人员(开发、运维人员)或许应该意识到在 Linux 容器生态中(诸如,Docker、Rkt、RunC、Lxcfs 等)内所运行的 Java 进程的实际行为与预期不符。当我们在没有任何调优参数(例如,最为简洁的的启动命令行:“ java -jar myapplication .jar”)的情况下执行 Java 应用程序时,JVM 将自行调整某些特定的参数,以在当前执行环境中获得最佳性能表现。
Luga Lee
2021/11/21
1.4K0
不得不提的容器 JVM
Java容器化参数配置最佳实践
Java是以VM为基础的,而云原生讲究的就是Native,天然的矛盾,虽然Quarkus是为GraalVM和HotSpot量身定制的K8s Native Java框架,生态原因切换成本太高,这种矛盾体现在很多方面,比如:当你在物理机或者虚拟机上配置 JVM 参数时,你可以选择使用-Xmx/-Xms 来指定 Java 堆大小,但这样指定的话,就固定了 JVM 堆占用大小,如果将 Java 应用程序移植到容器或者说 K8s Pod 中,K8S 本身有垂直扩容的能力,如果我把内存从 8G 增长到 16G,JVM 如何感知到呢?我们又该如何配置 Java 堆大小呢?本文我们讨论下如何在 Java 容器中参数配置的最佳实践。
用户5166556
2023/03/18
2.3K0
Java容器化参数配置最佳实践
Java进程管理规范
无论是在spring boot 还是spring cloud 项目中,随着应用的不断增多,JVM参数的统一管理的重要性就会凸显出来,否则你可能会遇到几个问题:
iginkgo18
2023/07/21
3870
解读 Java 云原生实践中的内存问题(必看)
Java 凭借着自身活跃的开源社区和完善的生态优势,在过去的二十几年一直是最受欢迎的编程语言之一。步入云原生时代,蓬勃发展的云原生技术释放云计算红利,推动业务进行云原生化改造,加速企业数字化转型。
用户1107783
2023/12/11
5420
解读 Java 云原生实践中的内存问题(必看)
Kubernetes Demystified:Java应用程序资源的限制
随着容器技术变得越来越复杂,越来越多的企业客户选择Docker和Kubernetes作为其应用平台的基础。但是,这些客户在实践中遇到许多问题。本系列文章介绍了阿里云集装箱服务团队帮助客户完成此流程的经验中的一些见解和最佳实践。
February
2018/11/19
1.4K0
聊聊新版JDK对docker容器的支持
即如果没有显式指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount, 那么JVM使用docker的cpu限制。如果docker有指定cpu limit,jvm参数也有指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount,那么以指定的参数为准。
code4it
2018/09/17
3K0
构建 Java 镜像的 10 个最佳实践
来源:toutiao.com/article/6959742944421200387/ 你想构建一个 Java 应用程序并在 Docker 中运行它吗?你知道在使用 Docker 构建 Java 容器有哪些最佳实践? 在下面的速查表中,我将为你提供构建生产级 Java 容器的最佳实践,旨在优化和保护要投入生产环境中的 Docker 镜像。 构建一个简单的 Java 容器镜像 让我们从简单的 Dockerfile 开始,在构建 Java 容器时,我们经常会有如下类似的内容: FROM mavenR
程序猿DD
2022/09/08
8230
避免容器中运行的Java应用被杀掉
今天测试环境遇到一个问题,一个Java的容器由于OOM频繁被Killed掉。这个问题还经常出现的,这里记录下解决过程。
jeremyxu
2019/11/07
2.2K0
Kubernetes 集群规模杂谈
早在 Kubernetes 1.2 时候,就已经宣布达到 1000 节点的规模了,在 1.6 版本更达到了 5000 节点的规模。各大厂也都有了各自的超大规模单一集群。然而普罗大众的情况是如何呢?Sysdig 在 2019 年度容器应用报告中得到的结果是,大于 50 节点规模的集群不足 10%,另外一个佐证是 Mohamed Ahmed 的一篇调查报告中也提供了类似的数据。这种情况的一种解释是,目前的应用阶段还比较早期,处于试探期间;然而从一个侧面来说,Sysdig 的调研对象针对的是生产应用,也就是说处于生产应用状态下的集群,绝大多数都是这种小规模集群。根据对 CNCF Landscape 中 Distribution 分类的产品的抽查,也可以看到随处可见的 Kubernetes As Service 类似功能的实现,这也证实了小集群协作方案的落地趋势。相对于少量大集群,多个小集群的差异在于:
崔秀龙
2020/04/02
9970
基于容器的Java内存参数解析
在基于物理的服务器(此处主要与容器平台进行区分,故此描述)上运行Java应用程序时,我们通常会使用Java虚拟机参数"-Xms、-Xmx"来指定Java堆内存的初始值和最大值。如果要将我们的应用程序移植到容器平台,如何在容器环境中配置Java堆内存大小呢?有没有最佳做法?在本文中,我们将讨论可用于指定Java堆内存大小的JVM参数以及最优选择。
Luga Lee
2021/12/09
1.8K0
基于容器的Java内存参数解析
解读Kubernetes常见退出码
在这篇文章中,我们将深入分析Kubernetes中的典型退出码127与137,解释它们是什么,K8s和Docker中常见的原因是什么,以及如何修复
zouyee
2024/03/04
6540
解读Kubernetes常见退出码
Java 垃圾收集器详解:CMS, G1, ZGC
Java 虚拟机(JVM)内置的垃圾收集机制是 Java 程序能够自动管理内存的关键。随着 Java 应用程序规模的增长和技术的进步,垃圾收集器的设计也在不断演进,以满足更高性能、更低延迟的需求。本文将详细介绍 CMS、G1 和 ZGC 这三种垃圾收集器,并提供一个详细的对比表格。
井九
2024/10/12
3280
Java 垃圾收集器详解:CMS, G1, ZGC
Java内存泄漏、性能优化、宕机死锁的N种姿势
本文介绍Java诸多优化实例:第一,排查堆上、堆外内存泄露;第二,使用arthas、jaeger、tcpdump、jstack做性能优化;第三,排查进程异常退出的原因,如被杀、System.exit、Java调用的C++发生Crash、Java内Crash;第四,排查死锁的原因,如log4j死锁、封装不严谨导致的死锁
PHP开发工程师
2021/05/14
8760
Java内存泄漏、性能优化、宕机死锁的N种姿势
谈JVM线程和内存参数合理性设置
在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!
京东技术
2023/08/25
1.8K0
谈JVM线程和内存参数合理性设置
Java程序员需要了解的—容器中的JVM资源该如何被安全的限制?
Java与Docker的结合,虽然更好的解决了application的封装问题。但也存在着不兼容,比如Java并不能自动的发现Docker设置的内存限制,CPU限制。
慕容千语
2019/06/13
1.5K0
常见的 OOM 异常分析(硬核干货)
在《Java虚拟机规范》的规定里,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生 OutOfMemoryError 异常的可能。
Java3y
2020/07/09
2K0
常见的 OOM 异常分析(硬核干货)
Java后端基础自测
这个就不多说了,主要是根据自己的简历上面的项目进行一个简短的概括使用的技术栈和什么背景解决了什么问题等等。
ma布
2024/10/21
1340
Java后端基础自测
在容器中使用 Java 的资源分配准则
如果说在容器中运行 Java 应用有一条核心定律,那么就是:对于在容器中运行的 Java 进程,不要手工设置 JVM 堆内存。相反的,设置容器的限制。
Java帮帮
2019/11/25
1.6K0
构建 Java 镜像的 10 个最佳实践
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/09/07
9710
构建 Java 镜像的 10 个最佳实践
Java 内存溢出(OOM)异常完全指南
Java 应用程序在启动时会指定所需要的内存大小,它被分割成两个不同的区域:Heap space(堆空间)和Permgen(永久代):
CG国斌
2020/05/15
4.8K0
相关推荐
不得不提的容器 JVM
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档