简体   繁体   English

C ++ / Qt应用程序的内存使用情况

[英]Memory usage of C++ / Qt application

I'm using OS X 10.5.6. 我正在使用OS X 10.5.6。 I have a C++ application with a GUI made with Qt. 我有一个使用Qt制作的GUI的C ++应用程序。 When I start my application it uses 30 MB of memory (reported by OS X Activity Monitor RSIZE). 当我启动应用程序时,它使用30 MB的内存(由OS X Activity Monitor RSIZE报告)。

I use this application to read in text files to memory, parse the data and finally visualize it. 我使用此应用程序将文本文件读入内存,解析数据并最终将其可视化。 If I open (read to memory, parse, visualize) a 9 MB text file Activity Monitor reports that my application grows from the initial 30 MB of memory used to 103 MB. 如果我打开(读取到内存,进行解析和可视化)一个9 MB的文本文件,活动监视器将报告我的应用程序从最初的30 MB内存增长到103 MB。

Now if the file is closed and the parsed and visualized data is deleted, the size of the application stays at 103 MB. 现在,如果关闭文件并删除已解析和可视化的数据,则应用程序的大小将保持为103 MB。 This sounds like a memory leak to me. 这听起来像是我的内存泄漏。 But if I open the file again, reading it to memory, parsing it and visualizing it the application stays at 103 MB. 但是,如果我再次打开文件,将其读取到内存中,对其进行解析并使其可视化,则应用程序将保持103 MB的大小。 No matter how many times I open the file (or another file of the same size) my applications memory use stays more or less unchanged. 不管我打开文件(或相同大小的另一个文件)多少次,我的应用程序内存使用情况或多或少保持不变。 Does this mean that it's not a memory leak? 这是否意味着这不是内存泄漏? If it was a leak the memory usage should keep growing each time the file is opened should it not? 如果是泄漏,则每次打开文件时内存使用量应保持增长,不是吗? The only time it grows is if I open a larger file than the previous one. 它唯一增长的时间是我打开的文件比上一个文件大。

Is this normal? 这正常吗? Is this platform or library dependent? 该平台或库依赖吗? Is this some sort of caching done by the OS or libraries? 这是操作系统或库完成的某种缓存吗?

This seems relatively normal, but all OS are slightly different. 这似乎是相对正常的,但是所有操作系统都略有不同。

In the usual application life cycle the application requests memory from the OS and is given memory in huge chunks that it manages (via the C/C++ standard libraries). 在通常的应用程序生命周期中,应用程序从OS请求内存,并为其分配巨大的内存(由C / C ++标准库管理)。 As the application acquires/releases memory this is all done internally within the application without recourse to the OS until the application has non left then a call is made to the OS for another huge chunk. 随着应用程序获取/释放内存,所有这些操作都在应用程序内部完成,而无需诉诸操作系统,直到应用程序还没有离开时,才向操作系统调用另一个巨大的块。

Memory is not usually returned to the OS until the application quits (though most OS do provide the mechanisms to do this if required and some C/C++ standard libraries will use this facility). 除非应用程序退出,否则通常不会将内存返回给操作系统(尽管大多数操作系统确实提供了必要的机制,某些C / C ++标准库将使用此功能)。 Instead of returning memory to the OS the application uses everything it has been given and does its own memory management. 应用程序无需将内存返回给操作系统,而是使用已提供的所有内容并进行自己的内存管理。

Though note: just because an application has memory does not mean that this is currently taking up RAM on a chip. 不过请注意:仅因为应用程序具有内存并不意味着它当前正在占用芯片上的RAM。 Memory that is sporadically used or has not been used in a while will be temporarily saved onto secondary/tertiary storage. 偶尔使用或一段时间未使用的内存将被临时保存到二级/三级存储中。

Activity Monitor: Is not a very useful tool for checking memory usage, as you have discovered it only displays the total actually allocated to the application. 活动监视器:它不是检查内存使用情况的非常有用的工具,因为您发现它仅显示实际分配给应用程序的总数。 It does not display any information about how the application has internal allocated this memory (most of which could be deallocated). 它不显示有关应用程序如何在内部分配此内存的任何信息(其中大多数可以释放)。 Check the folder where XCode lives, there are a broad set of tools for examining how an application works provided with the development environment. 检查XCode所在的文件夹,开发环境提供了许多工具来检查应用程序的工作方式。

NB: I have avoided using terms like page etc as these are nothing to-do with C/C++/Objective C and are all OS/hardware specific. 注意:我避免使用诸如page等的术语,因为这些术语与C / C ++ / Objective C无关,并且都是特定于OS /硬件的。

This sounds like a memory fragmentation problem to me. 对我来说,这听起来像是内存碎片问题。 Memory is acquired from OS in pages. 内存是从OS中分页获取的。 Pages are usually several kB large, eg 4 kB. 页面通常是几kB大,例如4 kB。 Now if you allocate, let's say, 100 MB of RAM for your objects, your memory allocator (new / malloc) asks OS for many free memory pages and allocates your objects on them. 现在,如果您为对象分配了100 MB的RAM,则您的内存分配器(new / malloc)会要求OS提供许多可用的内存页并在其上分配对象。 When your application finishes computations and deletes some , even most of, but not all of the previously allocated objects, the objects that were not deleted hold pages and disallow to return them back to the OS. 当您的应用程序完成计算并删除一些 (甚至大部分,但不是全部)先前分配的对象时,未被删除的对象将保留页面,并不允许将它们返回给OS。 A page can be returned only if all its memory is freed. 只有释放所有内存后,才能返回页面。 So in extreme cases, an 8B object can prevent a full 4kB page from being returned. 因此,在极端情况下,8B对象可以阻止返回完整的4kB页面。

The OS reports memory consumption by calculating the number of pages committed to your application, not by counting how much space your objects take on these pages. 操作系统通过计算提交给应用程序的页面数而不是通过计算对象在这些页面上占用的空间来报告内存消耗。 So if your memory is fragmented, the pages remain committed, and reported memory consumption stays the same. 因此,如果您的内存是零散的,则页面将保持提交状态,并且报告的内存消耗将保持不变。

The memory consumption does not grow on the second run, because on the second run the allocator reuses, previously acquired, mostly free pages. 内存消耗在第二次运行时不会增加,因为在第二次运行时,分配器会重用以前获取的,主要是空闲的页面。

The solution for fragmentation problems is usually preallocating a larger block of memory and using a custom memory allocator to allocate objects with similar lifetime from this larger block. 解决碎片问题的方法通常是预分配更大的内存块,并使用自定义内存分配器从该更大的块中分配具有相似生存期的对象。 Then, when you're done with objects, delete the whole block. 然后,在处理完对象后,删除整个块。

Another solution is switching to a fully garbage collected environment like Java or .NET - they have compacting garbage collectors that prevent such problems. 另一种解决方案是切换到Java或.NET等完全垃圾收集的环境-它们具有可防止此类问题的紧凑垃圾收集器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM