我有一个单例对象来处理请求。每个请求需要大约一毫秒的时间完成,通常更短。该对象不是线程安全的,并且它期望以特定格式封装在
我实现了生产者/消费者方法以快速工作:
- 客户端准备一个包含
但是,在进行小型内存基准测试时,我看到有很多这些对象被创建,并排在内存中最常见的对象列表的顶部。请注意,没有内存泄漏,GC可以在每次触发时很好地清理所有内容,但显然,这么多对象被快速创建,使Gen 0变得非常大。我想知道更好的内存使用可能会产生更好的性能。
我考虑将其中一些对象转换为结构体,以避免分配,特别是现在有一些新功能可以使用它们C#7.1。但我没有看到任何可以这样做的方式。
- 值类型可以在堆栈中实例化,但如果它们从一个线程传递到另一个线程,它们必须被复制到堆栈A->堆和堆->堆栈B。还有,当在队列中排队时,它从堆栈到堆。 - 单例对象是真正异步的。有一些内存处理,但90%的时间需要通过内部生产者/消费者调用外部。 -
是否有任何方法可以利用结构体来减少内存使用或/和提高性能?还有其他选择吗?
Request
类中的请求,并将结果作为Response
返回。此处理器还具有通过套接字发送/接收的另一个生产者/消费者。我实现了生产者/消费者方法以快速工作:
- 客户端准备一个包含
TaskCompletionSource<Response>
和预期Request
的RequestCommand
命令对象。
- 客户端将命令添加到“请求队列”(Queue<>
),并等待command.Completion.Task
。
- 不同的线程(实际的后台Thread
)从“请求队列”中提取命令,处理command.Request
,生成Response
,并使用command.Completion.SetResult(response)
标记命令已完成。
- 客户端继续工作。但是,在进行小型内存基准测试时,我看到有很多这些对象被创建,并排在内存中最常见的对象列表的顶部。请注意,没有内存泄漏,GC可以在每次触发时很好地清理所有内容,但显然,这么多对象被快速创建,使Gen 0变得非常大。我想知道更好的内存使用可能会产生更好的性能。
我考虑将其中一些对象转换为结构体,以避免分配,特别是现在有一些新功能可以使用它们C#7.1。但我没有看到任何可以这样做的方式。
- 值类型可以在堆栈中实例化,但如果它们从一个线程传递到另一个线程,它们必须被复制到堆栈A->堆和堆->堆栈B。还有,当在队列中排队时,它从堆栈到堆。 - 单例对象是真正异步的。有一些内存处理,但90%的时间需要通过内部生产者/消费者调用外部。 -
ValueTask<>
似乎不适合这里,因为事情是异步的。
- TaskCompletionSource<>
有一个状态,但它是object
,所以它会被装箱。
- 命令也会从线程跳到线程。
- 只有命令本身才能回收利用,其内容无法回收利用(TaskCompletionSource<>
和string
)。是否有任何方法可以利用结构体来减少内存使用或/和提高性能?还有其他选择吗?
Queue<T>
?尝试使用BlockingCollection<T>
或ConcurrentQueue<T>
。 - Dmitry Bychenko