笔记

万物寻其根,通其堵,便能解其困。
  博客园  :: 新随笔  :: 管理

关于报内存溢出相关处理笔记

Posted on 2025-06-09 11:05  草妖  阅读(10)  评论(0)    收藏  举报

目前,发现内存溢出在实际应用中常见的有这么两种情况:

  一、代码中存在while等循环,导致内存溢出。

  二、在后台代码中,部分接口报出内存溢出,但是部分接口正常。

第一种情况解决方案:

  第一种情况可以查看代码中的报错日志,一般可以解决,如果实在没有报错,可以按照下面步骤进行排查:

  步骤一:通过tasklist定位tomcat运行PID

C:\Users\Administrator\Desktop>tasklist
映像名称                       PID 会话名              会话#       内存使用
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          4 K
System                           4 Services                   0        140 K
tomcat9.exe                  10740 Services                   0  1,578,712 K

  步骤二:通过pid查看端口占用情况(如果存在大量端口占用,那么可能是访问网络请求拥堵造成的内存溢出,可以调查具体情况。)

-- 通过指定查询
C:\Users\Administrator\Desktop>netstat -aon | findstr 10740
-- 不指定查询
C:\Users\Administrator\Desktop>netstat -aon
活动连接
  协议  本地地址          外部地址        状态           PID
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       10740
  TCP    127.0.0.1:51373        127.0.0.1:51374        ESTABLISHED     10740
  TCP    127.0.0.1:51374        127.0.0.1:51373        ESTABLISHED     10740
  TCP    127.0.0.1:61439        127.0.0.1:6380         ESTABLISHED     10740
  TCP    172.16.41.128:60289    47.110.8.204:443       CLOSE_WAIT      10740
  TCP    172.16.41.128:60315    172.16.41.128:3306     ESTABLISHED     10740
  TCP    172.16.41.128:60320    172.16.41.128:3306     ESTABLISHED     10740
  TCP    172.16.41.128:60479    47.103.175.115:443     CLOSE_WAIT      10740
  TCP    172.16.41.128:60713    47.103.175.115:443     CLOSE_WAIT      10740

  步骤三:如果非网络拥堵造成的问题,可以通过jstack(Java Stack Trace,Java堆栈跟踪工具)查看虚拟机当前时刻的线程快照。如果存在死循环(locked <地址信息> (出问题的代码)),可以排除具体代码

C:\Users\Administrator\Desktop>jstack 10740
2025-06-09 11:00:12
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.112-b15 mixed mode):

"pool-17-thread-10" #1409 prio=5 os_prio=0 tid=0x000001cffdedd000 nid=0xb5a0 waiting on condition [0x00000042e71ff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000079a1a2730> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

"VM Thread" os_prio=2 tid=0x000001cff83d9000 nid=0x84a8 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x000001cfdebc7000 nid=0xc15c runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x000001cfdebc8800 nid=0x35e0 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000001cfdebca000 nid=0xb080 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000001cfdebcb800 nid=0x4644 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x000001cfdebce000 nid=0x2b74 runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x000001cfdebcf000 nid=0x3a90 runnable

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x000001cfdebd3000 nid=0x7c18 runnable

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x000001cfdebd4800 nid=0xb2ac runnable

"VM Periodic Task Thread" os_prio=2 tid=0x000001cffa22e800 nid=0xd55c waiting on condition

JNI global references: 7181


C:\Users\Administrator\Desktop>

 第二种情况解决方案:

  代码没问题,但是代码里层的嵌套太深,导致报出:StackOverflow,并且是在dofilter层溢出。

  这种情况,可以简化流程、将可以异步的步骤进行异步处理

  发生这种情况的原因:

  1、可能是计算机内存真的太小;

  2、jvm配置不合理。

    关于ParallelGCThreads不合理,可以参考JVM参数之ParallelGCThreads_-xx:parallelgcthreads-CSDN博客