• 再谈高性能Web服务器,MemoryPool的作用


    在以往使用c#实现scoket服务器中,通常遇到一个问题就是内存占用高,GC次数频繁,导致处理能力直线下降

    其主要原因是在处理socket请求时,大量的申请,复制内存,为了解决这个问题,NET Core 2.1引入了Span<T>,Memory<T>,MemoryPool<T>操作类型

    其主要目的是能够像c/c++一样,使用指针去访问,释放内存,提供一种高性能,可复用的内存处理方式

    在Kestrel 2.1中,就使用了Span<T>,Memory<T>,MemoryPool<T>处理socket请求,这也是Kestrel 2.1性能强大的原因之一

    MemoryPool是一个抽象类,提供了以下几个方法供使用

    public static MemoryPool<T> Shared { get; } //获取全局共享的默认内存池
    public abstract int MaxBufferSize { get; } //每次可获取的最大内存大小
    
    public void Dispose(); //释放内存池,申请的内存也一并释放
    public abstract IMemoryOwner<T> Rent(int minBufferSize = -1); //申请一个内存块,可以指定最小大小,默认为-1自动分配
    protected abstract void Dispose(bool disposing);

    申请到内存块 IMemoryOwner<T> 后,可以通过该接口获取Memory<T>, Memory<T>其实就是Span<T>的工厂

    Span<T>的操作方式以及性能跟Array<T>差不多,它是一种内存视图的表达方式,包含了目标内存的开始位置,内存长度

    我们操作的Span<T>时,首先将index加上start位置,然后再从对应的Memory<T>的位置获取数据

    Memory<T>与Span<T>都是struct类型,jit编译后,其对应真实的内存块,其读取也是通过内存指针直接操作,性能上跟c/c++是一样的

    Memory<T>在释放后将会return回MemoryPool中,MemoryPool将会重新分配内存块,实现内存的复用

    所以NET Core 2.1的Memory<T>与Span<T>类型,非常适合开发高性能Web服务器,游戏服务器

  • 相关阅读:
    【java】java 中 byte[]、File、InputStream 互相转换
    【java】java base64编码与解码
    git初级使用教程
    git学习五:eclipse使用git下载项目
    git学习四:eclipse使用git提交项目
    mybatis连接mysql数据库插入中文乱码
    SpringMVC加载配置Properties文件的几种方式
    zip 压缩文件夹
    java IOUtils下载图片
    spring工具类获取bean
  • 原文地址:https://www.cnblogs.com/Gool/p/9466078.html
Copyright © 2020-2023  润新知