net.sf.json:2.4 性能问题

时光总嘲笑我的痴心妄想 提交于 2020-01-04 15:33:39
起因:

月初这几天,某台服务器cpu频繁满载告警。
由于该台服务器部署了两个应用,一个web,一个后台。在凌晨先后启停服务后确定是后台应用导致。然后后台应用已经跑了很长时间,基本没有出过问题,怎么突然就出问题了呢?

定位:

联系相关开发人员,是最近有个适配改动了十几行代码。我想应该就是这几行代码导致的。和他一起review了他的代码,然而并没有发现代码有什么明显的改动。

去服务器看看,
使用jps查看java进程,获取到pid=31793,通过
jmap -histo 31793 > 1.txt
命令将内存中的对象信息输出到文件中,在这里插入图片描述
通过less查看发现,有内存中有十几万个该对象,正好,这个对象是改动的代码部分,但是实际考虑数据量及结合代码逻辑,不应该产生这么多对象。
使用
ps -mp 31793 -o THREAD,tid,time
命令获取java进程中各线程对CPU资源的使用情况:
在这里插入图片描述
发现,有3个鬼鬼祟祟的线程tid=31813,31814,31815占用了大量资源。将tid转换为16进制
printf "%x\n" 31813
16进制thread-id:7c45
从当前堆栈信息查看此线程

jstack 31793 > 2.txt

然后在2.txt文件中搜索7c45线程。
在这里插入图片描述
可以看到,占用大量资源的线程是在调用
JSONObject billData = JSONObject.fromObject(bd.getData());
将String转json时占用大量资源。
于是决定使用fastjson或者其他json来解决问题。
换用jackson后:业务恢复,cpu使用率正常。

其他:

本想继续看一看net.sf.json的源码,奈何不是org项目,无奈只能到此。以后技术的选用方面应该向大厂开源的靠拢。

测试了下性能:

10w个简单对象的json反序列化。

sf json:耗时788
fast json:耗时132

差距还是很大的
附测试代码:

import net.sf.json.JSONObject;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TestSFjson {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 1; i < 100000; i++) {
            User user = new User();
            user.setId(i);
            user.setAge(18);
            user.setName("hello" + i);
            user.setCreateTime(new Date());
            list.add(com.alibaba.fastjson.JSONObject.toJSONString(user));
        }
        long s = System.currentTimeMillis();
        for (String userStr : list) {
            JSONObject.fromObject(userStr);
        }
        System.out.println("sf json:耗时" +(System.currentTimeMillis() - s));
        long s2 = System.currentTimeMillis();
        for (String userStr : list) {
            com.alibaba.fastjson.JSONObject.parseObject(userStr);
        }
        System.out.println("fast json:耗时" +(System.currentTimeMillis() - s2));
    }
}

class User {
    private Integer id;
    private String name;
    private Integer age;
    private Date createTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!