实战|内部类导致反序列化抛出StackOverflowError异常

问题

客户端发出请求,通过网关访问项目A的接口获取资源数据,访问超时,报504

解决过程

  • 第一步:在项目A中先对接口进行单测,并打印耗时时间,显示500毫秒,故确认非接口性能问题
  • 第二步:网关调用远程调试项目A,在客户端发起请求至项目A该接口返回最终数据,时间只在一瞬间,故确认问题出在网关接收返回数据的环节
  • 第三步:远程调试网关,将断点定位在网关获取到项目A返回数据的那行代码,一步一步走下去,发现反序列返回数据的方法抛出StackOverflowError异常
    • StackOverflowError是栈溢出异常,发生原因是方法调用太多,栈空间不够用,常见于递归调用
  • 第四步:检查返回数据,发现返回数据内部一个属性值指向外部类的引用,发生了死循环引用,示例结构如下
data = {A@8281}{
  name = "名称外部"
  child = {Child@8284}{
     name = "名称内部"
     this$0 = {A@8281}{
       name = "名称外部"
       child = {Child@8284}{
          ...省略...循环
       }
     }
  }
}
  • 第五步:定位到问题出在返回数据出现了内部递归指向,即网关在反序列化返回数据时,先创建了A,然后创建A的属性name、child,但是属性child的属性又指向A,于是又初始化A属性,造成了死循环调用,最终抛出StackOverflowError异常
  • 第六步:回到项目A检查返回数据的数据结构,发现发生递归引用的那个属性的类型是一个内部类,经查阅,了解到内部类在创建时会默认拥有一个外部类实例的引用,故将内部类改成静态内部类,问题解决

解决思路

  1. 先排查项目接口本身是否有问题
  2. 然后网关调用接口,判断接口返回速度是否有问题
  3. 最后定位到网关返回环节有问题
  4. 根据该环节所报异常排查最终问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值