【问题标题】:When serializing large response, client receives ServiceStack exception, Out of Memory,序列化大响应时,客户端收到ServiceStack异常,内存不足,
【发布时间】:2013-05-31 20:17:30
【问题描述】:

我在带有 apache/mod_mono 的 linux 机器上有一个 ServiceStack RESTful Web 服务。

    public DataSetResponse Get(DataRequest req)
    {
        DataSetResponse Response = new DataSetResponse(); 
        DataSet BigData = new DataSet();

        this.Status = this.DataFetcher(ref BigData);   
        Response.Data = BigData;
        Response.Status = this.Status;         

        System.Threading.Thread.Sleep(30000);         
        return Response;
    }

当线程休眠时,我可以看到 mono 是 top 报告的内存的 8%。 30 多秒后,当单声道再次具有 cpu 活动时,内存上升到 90%,并引发内存不足异常。 Mono 会继续运行,但不会释放其内存。

在小型数据集(大小的 1/10)上,它似乎工作正常,并且单声道具有 1% 的内存。我认为内存增长发生在数据对象被序列化为 Json 之前,然后才流式传输到客户端。

这是正确的吗?更重要的是,我该如何解决这个问题?

【问题讨论】:

    标签: serialization mono servicestack


    【解决方案1】:

    我不知道您的服务器有多少 RAM,但如果它在单个请求上达到最大值,我假设由于它是一个 Web 服务,您希望为多个客户端提供服务,因此您可能会获得 2 个或更多在这些请求中,您可能需要考虑某种方式来流式传输或分块数据(即,客户端可以一次请求一页数据,并且他们可以继续请求更多页,直到他们获得整个数据集)。

    因此,您的请求 DTO 可能包含一个页面 #,您的数据获取器将抓取该下一页(基于您决定的每页记录数)并返回它。

    您的响应需要包括总页数和返回的页数,以便客户端可以决定继续获取数据。

    您可能在序列化之前看到 8% 的原因是该对象是其二进制格式 - 将其转换为一个大的 JSON 字符串会真正使其膨胀。

    您还可以考虑 ServiceStack 支持的其他一些二进制格式 - ProtoBuf 和 MessagePack。

    【讨论】:

    • 第一次请求就失败了,消耗了 3g 内存。我希望使用 POCO 而不是创建特殊协议。我在看 ProtoBuf.Net;我的客户端是移动设备 - 现在是 iOS。
    • 正确 - 您需要将第一个请求限制为单个页面,然后将其余数据分页到客户端。
    • 您也可以使用带有 MessagePack 格式的 POCO(不需要像 ProtoBuf 这样的特殊属性)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多