测试下来发现内存的使用并不是无限制的增大的,但是也是封顶600mb左右,并且这个数字在不同的容器实例以及实例重启之后近乎保持一致。
这个现象清楚的表明我们的容器中的应用并没有内存泄漏,只是有一块内存被分配了而没有得到释放。所以我开始把关注点转移到“运行在Kubernetes的.net程序是如何限制内存的“。
事实上Kubernetes最终也是将程序运行在docker容器中的,并且docker容器可以通过docker run --memory参数来限制内存的使用。所以我怀疑也许是Kubernetes并没有传递任何有关内存限制的参数到docker容器实例中,所以.net程序理所当然的认为当前机器有好多好多的可用内存可以使用。
但是并不是这种情况,我们发现相反的内容(因为作者怀疑是Kubernetes没有传递和内存相关的参数)在the documentation.
The spec.containers[].resources.limits.memory is converted to an integer, and used as the value of the --memory flag in the docker run command.
(这句话的意思是Kubernetes的spec.containers[].resources.limits.memory会自动沿用docker run中的--memory参数所设置的整数值)
这似乎又到了另一个死胡同了。我也尝试在自己电脑里的docker中运行api程序,并且通过--memory参数传递多种内存限定值,但是1.我不能复现上述600mb内存使用的场景,内存只保持在150mb左右,2.也没有观察到容器实例运行的超过它的内存限制,即使我通过--memory参数来指定一个小于150mb的值,这个容器实例依然能够在这个更小的内存限定值下运行的完好。
很早的时候我也在github上提过一个关于内存泄漏的issue关联到Kestrel(core的一个基于libuv的新的服务器),并且在这一点上,Tim Seaward发了一个有趣的suggestion关于检查我的应用在不同环境下所打印出的cpu的个数,因为cpu的是影响内存使用的一个巨大因素。
我尝试在代码里通过Environment.ProcessorCount在不同的环境下打印出的数量如下:
On my machine, just doing dotnet run, the value was 4.