深圳做网站推荐哪家公司谷歌网页版登录入口
2026/3/29 21:10:28 网站建设 项目流程
深圳做网站推荐哪家公司,谷歌网页版登录入口,郑州市房产信息网官方网站,wordpress头像解决半夜收到告警#xff1a;服务挂了#xff0c;重启后又挂。 一看日志#xff1a;OutOfMemoryError。 OOM是后端最头疼的问题之一#xff0c;因为往往不是立刻暴露#xff0c;而是慢慢积累#xff0c;突然爆发。这篇整理一下排查思路。OOM的常见类型 Java OOM java.lang.Ou…半夜收到告警服务挂了重启后又挂。一看日志OutOfMemoryError。OOM是后端最头疼的问题之一因为往往不是立刻暴露而是慢慢积累突然爆发。这篇整理一下排查思路。OOM的常见类型Java OOMjava.lang.OutOfMemoryError: Java heap space # 堆内存不足 java.lang.OutOfMemoryError: GC overhead limit exceeded # GC回收不了内存 java.lang.OutOfMemoryError: Metaspace # 元空间不足类太多 java.lang.OutOfMemoryError: Unable to create new native thread # 线程太多 java.lang.OutOfMemoryError: Direct buffer memory # 直接内存不足Go OOMGo没有显式的OOM错误但会被操作系统OOM Killer杀掉# dmesg查看dmesg|grep-iout of memorydmesg|grep-ioom# 输出# Out of memory: Killed process 12345 (your_app)Java OOM排查第一步获取堆dump方式一JVM参数自动dump# 启动参数加上-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/var/log/java/heapdump.hprofOOM时自动生成dump文件。方式二手动dump# 找到进程PIDjps -l# 生成dumpjmap -dump:formatb,fileheapdump.hprofPID方式三Arthas# 启动Arthasjava -jar arthas-boot.jar# dump堆heapdump /tmp/heapdump.hprof第二步分析堆dump工具一MATMemory Analyzer ToolEclipse MAT是最强大的堆分析工具。1. 打开 heapdump.hprof 2. 选择 Leak Suspects Report自动分析可能的泄漏点 3. 查看 Dominator Tree按内存占用排序 4. 查看 Histogram按类统计对象数量和大小工具二VisualVM# 启动VisualVMjvisualvm# File → Load → 选择hprof文件工具三jhat命令行jhat -port7000heapdump.hprof# 浏览器打开 http://localhost:7000常见Java OOM场景1. 内存泄漏集合只增不删// 问题代码publicclassCache{privatestaticMapString,ObjectcachenewHashMap();publicvoidput(Stringkey,Objectvalue){cache.put(key,value);// 只增不删内存迟早爆}}MAT分析HashMap占用几个G里面有几百万个对象。解决用LRU缓存替代设置最大容量使用WeakHashMap// 修复privatestaticMapString,ObjectcachenewLinkedHashMapString,Object(10000,0.75f,true){OverrideprotectedbooleanremoveEldestEntry(Map.EntryString,Objecteldest){returnsize()10000;// 超过1万自动淘汰}};2. 大对象一次性加载大量数据// 问题代码publicListOrdergetAllOrders(){returnorderDao.selectAll();// 100万条数据全加载到内存}解决分页查询、流式处理// 修复流式查询publicvoidprocessAllOrders(ConsumerOrderconsumer){try(StreamOrderstreamorderDao.selectAllAsStream()){stream.forEach(consumer);}}3. 线程泄漏// 问题代码publicvoidhandleRequest(){newThread(()-{// 处理逻辑}).start();// 每个请求创建一个线程}线程多了会报Unable to create new native thread。解决使用线程池privatestaticExecutorServiceexecutorExecutors.newFixedThreadPool(100);publicvoidhandleRequest(){executor.submit(()-{// 处理逻辑});}4. 连接泄漏// 问题代码publicUsergetUser(intid){ConnectionconndataSource.getConnection();// 查询...returnuser;// 没有close连接泄漏}解决用try-with-resourcespublicUsergetUser(intid){try(ConnectionconndataSource.getConnection();PreparedStatementpsconn.prepareStatement(SELECT * FROM users WHERE id ?)){ps.setInt(1,id);// ...}// 自动关闭}实时监控# 查看堆内存使用jstat -gcPID1000# S0C S1C S0U S1U EC EU OC OU MC MU ...# 1024.0 1024.0 0.0 512.0 8192.0 4096.0 20480.0 15360.0 ...# 查看GC情况jstat -gcutilPID1000# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT# 0.00 50.00 50.12 75.00 95.23 92.12 123 2.345 456 89.123 91.468O老年代持续增长且Full GC后不下降基本就是内存泄漏。Go OOM排查Go没有堆dump这个概念但有pprof。第一步开启pprofimport_net/http/pproffuncmain(){gofunc(){http.ListenAndServe(:6060,nil)}()// ...}第二步分析内存方式一命令行# 查看当前内存分配go tool pprof http://localhost:6060/debug/pprof/heap(pprof)top10Showing nodes accountingfor1.5GB,90% of1.67GB total flat flat% sum% cum cum% 800MB47.90%47.90% 800MB47.90% main.leakyFunction 400MB23.95%71.86% 400MB23.95% bytes.makeSlice...(pprof)list leakyFunction# 显示代码级别的内存分配方式二Web界面go tool pprof -http:8080 http://localhost:6060/debug/pprof/heap# 浏览器打开可视化分析方式三对比两个时间点# 先保存一份curl-o heap1.out http://localhost:6060/debug/pprof/heap# 过一段时间再保存curl-o heap2.out http://localhost:6060/debug/pprof/heap# 对比go tool pprof -base heap1.out heap2.out# 显示增量更容易发现泄漏常见Go OOM场景1. goroutine泄漏// 问题代码funchandleRequest(chchanint){gofunc(){val:-ch// 如果没人发送永远阻塞process(val)}()}goroutine不退出内存持续增长。检测# 查看goroutine数量curlhttp://localhost:6060/debug/pprof/goroutine?debug1|head-1# goroutine profile: total 10234# 数量一直涨就是泄漏解决用context控制生命周期funchandleRequest(ctx context.Context,chchanint){gofunc(){select{caseval:-ch:process(val)case-ctx.Done():return// 超时退出}}()}2. slice底层数组未释放// 问题代码funcgetFirstElement(data[]byte)[]byte{returndata[:1]// 底层数组还是那个大的}// 假设data是1GB返回的slice虽然只有1字节但底层数组还是1GB解决复制出来funcgetFirstElement(data[]byte)[]byte{result:make([]byte,1)copy(result,data[:1])returnresult}3. time.After泄漏// 问题代码for{select{case-ch:// ...case-time.After(time.Second):// 每次循环创建新timer// ...}}time.After创建的timer在触发前不会被GC。解决复用timertimer:time.NewTimer(time.Second)defertimer.Stop()for{select{case-ch:if!timer.Stop(){-timer.C}timer.Reset(time.Second)case-timer.C:timer.Reset(time.Second)}}4. 字符串拼接// 问题代码funcbuildString(items[]string)string{result:for_,item:rangeitems{resultitem// 每次都创建新字符串}returnresult}解决用strings.BuilderfuncbuildString(items[]string)string{varbuilder strings.Builderfor_,item:rangeitems{builder.WriteString(item)}returnbuilder.String()}Go内存相关参数# 设置最大内存限制Go 1.19GOMEMLIMIT4GiB ./your_app# 设置GC目标百分比默认100即内存翻倍时触发GCGOGC50./your_app# 更激进的GC通用排查技巧1. 看进程内存# 查看进程内存psaux|grepyour_app# RSS: 物理内存占用# VSZ: 虚拟内存占用# 更详细cat/proc/PID/status|grep-EVmRSS|VmSize|VmPeak# VmPeak: 峰值虚拟内存# VmRSS: 当前物理内存2. 看系统内存# 整体内存使用free-h# 各进程内存排序psaux --sort-%mem|head-20# 实时监控top# 按M键按内存排序3. 监控内存变化趋势# 每秒记录一次RSSwhiletrue;doecho$(date)$(ps-orss-pPID)sleep1donememory.log内存持续增长不下降 泄漏。4. OOM Killer日志# 查看被OOM Killer杀掉的进程dmesg|grep-ikilled processjournalctl -k|grep-ioom# 查看OOM Score分数越高越容易被杀cat/proc/PID/oom_score预防措施1. 设置内存限制Javajava -Xmx4g -Xms4g -jar app.jarGoGOMEMLIMIT4GiB ./appDockerservices:app:mem_limit:4g2. 监控告警# Prometheus告警规则-alert:HighMemoryUsageexpr:process_resident_memory_bytes / 1024 / 10243000for:5mlabels:severity:warningannotations:summary:Memory usage 3GB3. 定期压测# 压测看内存是否持续增长wrk -t12 -c400 -d30m http://localhost:8080/api/test# 同时监控内存watch-n1ps -o rss -p PID4. Code Review检查点集合是否有容量限制资源连接、文件、流是否正确关闭线程/goroutine是否有退出机制大数据量是否分批处理缓存是否有淘汰策略总结OOM排查步骤获取现场堆dumpJava、pprofGo分析大对象找到占用内存最多的对象/函数定位代码追溯到具体的代码位置分析原因是泄漏还是确实需要这么多内存修复验证改代码压测验证常见原因集合只增不删资源没关闭线程/goroutine泄漏一次性加载大量数据缓存没有淘汰策略记住OOM往往是慢慢积累的。上线后持续观察内存趋势发现缓慢增长要及时排查别等爆了再处理。有问题评论区聊。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询