这是Linux Mono应用程序中的内存泄漏吗?

时间:2014-08-31 20:10:27

标签: linux memory mono sgen

我一直在努力确定我所看到的是我的Debian Wheezy Mono-Sgen 2.10.8.1-8嵌入式应用程序中的内存泄漏。该系统有512MB的RAM。交换已禁用。我一直在研究如何理解Linux如何管理进程内存,以便得出我所看到的实际上是Mono-Sgen中某处的内存泄漏。我很确定它不是我的应用程序,因为我在经过数周的恒定运行时间之后对它进行了多次分析,并且GC内存总是回落到应用程序的基线。从我的应用的角度来看,没有任何物体泄漏。这并不意味着Mono-Sgen内部没有泄漏,但我还没有确定这一点,也可能不是。

我试图限制我的Mono-Sgen堆,因为大堆的单声道默认值为512MB,因为这是我的系统所有,我认为我需要限制它以防止来自Linux的OOM。我对Mono-Sgen的配置如下:

export MONO_GC_PARAMS = major = marksweep-fixed,major-heap-size = 32m,nursery-size = 4m,evacuation-threshold = 75

根据我的理解,我使用标记和扫描固定主要堆,固定大小为32MB,默认托儿所大小为4MB,如果任何主要堆分配桶掉落,Mono-Sgen将在主堆上执行复制收集低于75%用于防止碎裂。我把默认值提高了66%。

由于断电导致重置,我的设备目前已经启动了6天多一点。当我的应用程序首次启动时,我等待大约10分钟以确保它已完全初始化,然后我快速拍摄/ proc / PID / status文件以获得其内存使用的基线。今天,我又去了另一家快餐店,看看我在哪里,而且一如既往,我的虚拟,驻留和Mono-Sgen流程实例的数据再次增长。它尚未突破初始化期间发生的高水位线,但上次我做了这个测试。我无法做到的以及我想要完成的是让它耗尽系统的所有物理内存。我需要知道这是否实际上是内存泄漏,或者在某些时候Linux将要回收我的进程已经分配的一些页面。

我注意到的一件事是,即使知道我没有交换,我的Mono-Sgen进程的驻留大小总是比数据计数少30MB。根据我的理解,数据计数是堆分配的数量,驻留大小是实际在物理内存中的,虚拟是已分配的,不一定使用。

我的假设是Linux只是Linux而不是浪费时间或内存,除非必须这样做。我假设因为系统负载非常轻,Linux有0内存压力要做任何事情来回收内存,以免Mono-Sgen继续分配和增加堆,我希望是有一些实际的内存压力,Linux正在进行介入并回收未真正使用的页面。

我已经读过,在以前分配的内存上调用free时,Linux不会缩小进程的已分配内存大小。我不明白为什么,除非Linux是Linux,它只会在必要时才这样做。但我担心的是我需要等多久才能发生这种情况。

这是内存泄漏还是Linux会在内存压力开始启动时回收此进程的常驻和数据大小之间的页面差异?我已经搜索并阅读了关于这个主题的所有内容,我找不到我想要的答案,而且我真的不想等一个月才能知道我的应用程序是否会因为OOM杀手而反弹。无论如何我会:)但我想事先知道。

我已经研究过使用Mono-Sgen 2.10.8.1-8的潜在内存泄漏,但我正在做什么(使用大量的process.start()调用本机Linux应用程序)大多数类型的错误伤害我的不是这个版本。我试图更新到Jessie的Mono-Sgen版本(我认为是3.2.8),但它在我的系统上崩溃了,所以我又回到了稳定的Mono-Sgen 2.10.8.1-8版本,出于更多未知的恐惧。

附件是典型内存信息的大量快照,我的注意力主要集中在/ proc / PID / status返回的内容。

任何信息都将一如既往地受到高度赞赏,我希望我只是不明白Linux如何在一个负载较轻的系统上回收内存。

/proc/PID/status diff of running Mono-Sgen process after 6 days of Uptime

free -tmh of Linux Embedded System with 512MB RAM, no Swap

Top command results for Linux Embedded System with 512MB RAM, no Swap

1 个答案:

答案 0 :(得分:1)

您可以设置以下环境变量来控制malloc的内部内存分配。设置后,它会回答你的问题。如果您想了解其他选项,请参阅:

http://man7.org/linux/man-pages/man3/mallopt.3.html

导出MALLOC_MMAP_THRESHOLD_ = 8192

导出MALLOC_ARENA_MAX = 4