为什么这个简单的 GTK3 应用程序会消耗如此多的内存?

Why this simple GTK3 application consumes so much memory?

我创建了一个简单的应用程序,它只创建和显示空的 50x50 window,但它已经消耗了 20MB 的内存。我的目标是低内存设备,所以每一兆字节都很重要。是什么导致 GTK 消耗所有内存?是否可以减少内存使用量?

程序的完整源代码如下:

#include <gtk/gtk.h>
int main(int argc, char* argv[]) {
  gtk_init(&argc, &argv);

  GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DOCK);
  gtk_window_set_default_size(GTK_WINDOW(window), 50, 50);
  gtk_window_move(GTK_WINDOW(window), 50, 50);

  gtk_widget_show_all(window);
  gtk_main();
  return 0;
}

这是我用它编译的:

gcc -std=gnu99 -Wall -o example main.c $(pkg-config --cflags --libs gtk+-3.0)

这是最终的内存使用情况:

$ ps -FC example
UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
platon    4214 11052  7 84812 20996   1 16:13 pts/5    00:00:00 ./example

(ps 以 KB 为单位测量内存使用情况,因此为 20996KB 或 ~21MB)

我在 linux 4.11.6,x86_64.

上使用 gtk3 版本 3.22.16

问题背景:目标系统是相对低内存的 PC(200-400 MB 内存)。应用程序是该 PC 上类似信息亭的界面,具有相对复杂的 GUI 结构(许多页面和可能的交互)。而且我宁愿避免手动重新实现所有 GUI 逻辑(在较低级别的库之上),所以我正在寻找更高级别的东西 - 似乎只有 GTK 和 Qt space(Qt 只能在 C++ 中使用,这很痛苦)。

我 运行 你的程序(用 -O1 优化)在后台,而不是用 pmap(1) 观察它的(虚拟)内存映射。它在 Debian/Sid/x86-64 上的 349 个内存段中消耗 335752K(即 335Mbytes)。加载了 77 个不同的共享库。顺便说一句,一旦您使用文本和字体,它们也会进入虚拟地址 space。 ps -FCSZ 提供了大约 84Mb,为 RSS 提供了 21Mb(也可以尝试使用 pmap -x 来获取 RSS 详细信息)。

您应该在您自己的(目标)系统上使用 pmap 并得出您自己的关于什么在消耗内存的结论。如果 pmap 不可用且进程的 pid 为 1234,请参阅 /proc/1234/maps(提供与 pmap 相同的 信息 并由 [=15= 解析]), 阅读 proc(5)

顺便说一句,我对这么高的消费并不感到惊讶。多想想 GUI 使用的所有隐含资源(你会通过研究 pmap 的输出或使用 strace(1) ...). See also and follow the links I gave there. My opinion is that you need in practice a gigabyte (or at least half of it) of RAM (like on most RaspberryPIs 来猜测)到 运行 现代 GUI 工具包,如 Qt或 GTK。请注意,如今 1 GB 的 RAM 非常便宜,因此您的公司可能需要销售数百万台设备才能支付多年额外开发工作所需的费用,以适应仅几百兆字节的内存。

(也许你最好使用较低级别的东西,例如 libsdl, or libX11 but see

so each megabyte really counts

那么你不需要一个功能齐全的 GUI 工具包(或者你应该买一个功能更强大的硬件和 1 GB 的 RAM)。您可以只针对原始 Wayland (or X11) display server (at the expense of many years of development efforts, or by accepting a much less sophisticated GUI). BTW QT(也许还有 GTK)具有专门的嵌入式 - 或帧缓冲区 - 变体(这可能会稍微减少资源消耗)。

PS。我猜你的 OS 是某种 Linux 变体;我建议阅读像 Operating Systems : Three Easy Pieces 这样的教科书(可免费合法下载),以更好地了解 OS 的工作原理。

在声称您的进程占用大量 RAM 之前,您应该回答以下问题:

  1. 添加更多小部件时,RAM 量会增加多少?内存成本可能约为 20 MB + 0.1 MB*k,其中 k 是小部件的数量。
  2. 除了你的GUI,你还有多少个进程。如果每个小部件的成本低于 0.1 MB(我相信只要你不加载巨大的图像),你可以拥有 1000 个小部件没有任何问题,只要你不 运行 任何其他占用大量内存。

此外,由于您的目标系统内存少于 1 gig,请调查在 32 位模式下 运行 的可能性以及该环境中的内存使用情况。这会将每个指针的大小减小 2 倍。这主要影响指针繁重的应用程序。