专业汉语词典知识平台,分享汉字词语知识、历史文学知识解答!

励北网
励北网

StackOverflowError原因,StackOverflowError解决办法

来源:小易整编  作者:小易  发布时间:2023-02-14 07:00
摘要:StackOverflowError原因,StackOverflowError解决办法如果你对StackOverflowError有一定的了解,就可以知道出现这个问题的主要原因就是调用栈太深,比如常见的无限递归调用。那本文要介绍的Dubbo...

StackOverflowError原因,StackOverflowError解决办法

如果你对StackOverflowError有一定的了解,就可以知道出现这个问题的主要原因就是调用栈太深,比如常见的无限递归调用。那本文要介绍的Dubbo抛出的这个StackOverflowError又是什么原因呢?且往下看。

StackOverflowError原因,StackOverflowError解决办法~noop

StackOverflowError重现问题

话不多说,直入主题。这次碰到的StackOverflowError非常好重现,只需要如下简短的代码即可。需要注意的是这里调用的是
com.alibaba.dubbo.common.json.JSON,而不是fastjson中的com.alibaba.fastjson.JSON:

package com.afei.test.dubbo.provider.main;
import com.alibaba.dubbo.common.json.JSON;
import java.util.Locale;
public class DubboTest {
 public static void main(String[] args) throws Exception {
 Locale locale = Locale.getDefault();
 System.out.println(JSON.json(locale));
 }
}

运行这段代码能得到如下异常:

Exception in thread "main" java.lang.StackOverflowError 

at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) 

at sun.util.locale.provider.LocaleResources.getLocaleName(LocaleResources.java:233)

at java.util.Locale.getDisplayName(Locale.java:1879) 

at java.util.Locale.getDisplayName(Locale.java:1845) 

at com.alibaba.dubbo.common.bytecode.Wrapper0.getPropertyValue(Wrapper0.java)

at com.alibaba.dubbo.common.json.GenericJSONConverter.writeValue(GenericJSONConverter.java:125)

at com.alibaba.dubbo.common.json.GenericJSONConverter.writeValue(GenericJSONConverter.java:73) 

at com.alibaba.dubbo.common.json.GenericJSONConverter.writeValue(GenericJSONConverter.java:129) 

at com.alibaba.dubbo.common.json.GenericJSONConverter.writeValue(GenericJSONConverter.java:73) 

at com.alibaba.dubbo.common.json.GenericJSONConverter.writeValue(GenericJSONConverter.java:129) 

at com.alibaba.dubbo.common.json.GenericJSONConverter.writeValue(GenericJSONConverter.java:73) ... ...

StackOverflowError分析原因

由这个异常堆栈信息,我们很容易知道在GenericJSONConverter中的第73行和129行之间出现了无限递归调用,打开dubbo源码并debug,发现在调用GenericJSONConverter中的writeValue()方法时,首先会判断需要序列化的对象的类型。当对象是如下类型时会特殊处理:

  1. 原生类型或者封装类型;

  2. JSONNode类型;

  3. 枚举;

  4. 数组;

  5. Map;

  6. 集合类型;

如果需要序列化的对象是其他类型,比如这里的Locale类型,序列化逻辑如下所示:

jb.objectBegin();
Wrapper w = Wrapper.getWrapper(c);
// 得到这个对象的所有属性
String pns[] = w.getPropertyNames();
// 遍历属性
for( String pn : pns )
{
 // 被序列化的对象Locale并不是Throwable类型,忽略这段逻辑
 if ((obj instanceof Throwable) && (
 "localizedMessage".equals(pn) 
 || "cause".equals(pn) 
 || "stackTrace".equals(pn))) {
 continue;
 }
 jb.objectItem(pn);
 // 得到当前遍历属性的值
 Object value = w.getPropertyValue(obj,pn);
 if( value == null || value == obj)
 jb.valueNull();
 else
 // 无限递归死循环出现在这里
 writeValue(value, jb, writeClass);
}

通过这段源码的分析,我们大概可以知道Locale的属性中肯定有Locale类型的属性。由于有Locale类型的属性,导致继续调用GenericJSONConverter中的writeValue()方法,从而无限递归下去,让我们继续Debug源码验证这个猜想。

Debug到String pns[] = w.getPropertyNames();,我们通过查看Locale的属性pns[]可以验证我们前面的猜想,如下图所示。Locale属性availableLocales的类型还是Locale,从而出现死循环直到抛出StackOverflowError:

StackOverflowError原因,StackOverflowError解决办法

Locale中有Locale类型的属性

StackOverflowError解决问题

那么如何解决这个问题呢?很简单,不要使用dubbo中的JSON,改为使用fastjson中的JSON,或者jackson和GSON都可以:

Locale locale = Locale.getDefault();
System.out.println(com.alibaba.fastjson.JSON.toJSON(locale));
System.out.println(new com.google.gson.Gson().toJson(locale));

本文地址:百科问答频道 https://www.neebe.cn/wenda/903077.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!


百科问答
小编:小易整编
相关文章相关阅读
  • Excel中countif函数的使用方法

    Excel中countif函数的使用方法

    Excel中有很多函数,很多都可以为我们大大减少计算的时间,一步就得出结果,很多朋友在使用countif函数时,会出现一些错误导致不成功,我们这就来给你详细讲讲countif函数是应该如何使用的。countif函数的含义...

  • 房蚁的使用方法

    房蚁的使用方法

    房蚁的使用方法如下操作方法011.关注房蚁022.订阅一下作业区域033.收到委托成功通知,点击查看...

  • 虚拟机关机命令poweroff方法

    虚拟机关机命令poweroff方法

    虚拟机是虚拟技术。许多用户将使用虚拟机上的命令自定义操作关机,使其方便快速,有更多的时间来处理其他事情,然后没有其他更容易的Poweroff应该不是命令?让我们来看看。虚拟机命令Poweroff方法首先,Poweroff.1,Powerof...

  • 鼠标不灵怎么办 鼠标不灵的常见解决方法

    鼠标不灵怎么办 鼠标不灵的常见解决方法

    我就叫她去网上或者商城在买个,他说前几天刚买的,还是新的啊,问我是不是电脑或者接口的问题,我到同事家里,发现是他电脑接口和鼠标接口没接好的问题。今天想想,有好多对电脑不是很懂的朋友遇到这种问题都不知道怎么去解决,所有学无忧小编就为大家都讲述...

  • 如何截取一段音乐方法

    如何截取一段音乐方法

    音乐是人生中不可缺少精神食粮,音乐能陶冶情操,能治疗疾病,能让人精神放松,缓解疲惫的身躯,用途很多。很多人喜欢DIY,比如制作个性的电脑开关机音乐、手机铃声等短时间的音频,这就需要使用剪切工具剪切音乐并截取出如副歌等的一小段音频出来。其中剪...

  • 用ps抠公章的方法 公章怎么抠图

    用ps抠公章的方法  公章怎么抠图

    Photoshop主要处理以像素所构成的数字图像,使用其众多的编修与绘图工具,可以有效地进行图片编辑和加工,很多小伙伴爱用这个软件来P图。然而,有的用户不知道如何用ps抠公章。别着急哦,小编今天就教你如何轻松搞定。具体如下:1.在这之前,...

  • 打印机常见故障及解决方法大全

    打印机常见故障及解决方法大全

      1.故障现象:发出打印命令后,打印机无反应,系统提示打印机是否联机及电缆连接是否正常。  分析与维修:这可能是打印机电源线末插好、打印电缆未正确连接或接触不良、计算机并口损坏等原因造成的。先按打印机开关,看打印机能不能启动。如不能启动(...

  • 王卡助手绑定腾讯王卡的方法

    王卡助手绑定腾讯王卡的方法

    腾讯王卡用户可通过“王卡助手”微信公众号查询、办理业务,以下详细介绍王卡助手绑定方式;操作方法01①微信添加“王卡助手”公众号,点击“关注公众号”02②进入“王...

  • 周排行
  • 月排行
  • 年排行

精彩推荐