Memory leaks Pango中的内存泄漏
我在Cairo旁边使用Pango库,没有GTK,我正在MacOSX上编译一个试驾应用程序。我有一个内存泄漏问题,我跟踪到这个函数:Memory leaks Pango中的内存泄漏,memory-leaks,cairo,pango,pangocairo,Memory Leaks,Cairo,Pango,Pangocairo,我在Cairo旁边使用Pango库,没有GTK,我正在MacOSX上编译一个试驾应用程序。我有一个内存泄漏问题,我跟踪到这个函数: void draw_with_cairo (void) { PangoLayout *layout; PangoFontDescription *desc; int i; cairo_save (cr); cairo_scale (cr, 1, -1); cairo_translate (cr, 0, -HEIGHT
void draw_with_cairo (void)
{
PangoLayout *layout;
PangoFontDescription *desc;
int i;
cairo_save (cr);
cairo_scale (cr, 1, -1);
cairo_translate (cr, 0, -HEIGHT);
cairo_translate (cr, 400, 300);
layout = pango_cairo_create_layout (cr);
pango_layout_set_text (layout, "Test", -1);
desc = pango_font_description_from_string ("BMitra 32");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
for (i = 0; i < 12; i++)
{
int width, height;
double angle = iter + (360.0 * i) / 12;
double red;
cairo_save (cr);
red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
cairo_set_source_rgb (cr, red, 0, 1.0 - red);
cairo_rotate (cr, angle * G_PI / 180.);
pango_cairo_update_layout (cr, layout);
pango_layout_get_size (layout, &width, &height);
cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - 250);
pango_cairo_show_layout (cr, layout);
cairo_restore (cr);
}
cairo_restore (cr);
g_object_unref (layout);
}
这是最后一级的未过滤输出:
Executing vmmap -resident 25751 at end
Process: main [25751]
Path: /PATH/OMITTED/main
Load Address: 0x109b9c000
Identifier: main
Version: ???
Code Type: X86-64
Parent Process: bash [837]
Date/Time: 2016-01-30 23:28:35.866 +0330
Launch Time: 2016-01-30 23:27:35.148 +0330
OS Version: Mac OS X 10.11.2 (15C50)
Report Version: 7
Analysis Tool: /Applications/Xcode.app/Contents/Developer/usr/bin/vmmap
Analysis Tool Version: Xcode 7.0.1 (7A1001)
----
Virtual Memory Map of process 25751 (main)
Output report format: 2.4 -- 64-bit process
VM page size: 4096 bytes
==== Non-writable regions for process 25751
==== Legend
SM=sharing mode:
COW=copy_on_write PRV=private NUL=empty ALI=aliased
SHM=shared ZER=zero_filled S/A=shared_alias
==== Summary for process 25751
ReadOnly portion of Libraries: Total=219.6M resident=112.2M(51%) swapped_out_or_unallocated=107.5M(49%)
Writable regions: Total=155.7M written=5448K(3%) resident=104.1M(67%) swapped_out=0K(0%) unallocated=51.6M(33%)
VIRTUAL RESIDENT REGION
REGION TYPE SIZE SIZE COUNT (non-coalesced)
=========== ======= ======== =======
Activity Tracing 2048K 12K 2
Dispatch continuations 8192K 32K 2
Kernel Alloc Once 8K 8K 3
MALLOC guard page 32K 0K 7
MALLOC metadata 364K 84K 11
MALLOC_LARGE 260K 260K 2 see MALLOC ZONE table below
MALLOC_LARGE (empty) 980K 668K 2 see MALLOC ZONE table below
MALLOC_LARGE metadata 4K 4K 2 see MALLOC ZONE table below
MALLOC_SMALL 32.0M 880K 3 see MALLOC ZONE table below
MALLOC_TINY 104.0M 102.1M 7 see MALLOC ZONE table below
STACK GUARD 56.0M 0K 3
Stack 8264K 60K 3
VM_ALLOCATE 16K 8K 2
__DATA 16.7M 13.6M 217
__IMAGE 528K 104K 2
__LINKEDIT 92.4M 22.5M 34
__TEXT 127.2M 89.6M 220
__UNICODE 552K 476K 2
mapped file 32.2M 13.7M 4
shared memory 328K 172K 10
=========== ======= ======== =======
TOTAL 481.6M 244.3M 518
VIRTUAL RESIDENT ALLOCATION BYTES REGION
MALLOC ZONE SIZE SIZE COUNT ALLOCATED % FULL COUNT
=========== ======= ========= ========= ========= ====== ======
DefaultMallocZone_0x109bd0000 136.3M 103.2M 151952 65.4M 48% 10
GFXMallocZone_0x109bd3000 0K 0K 0 0K 0
=========== ======= ========= ========= ========= ====== ======
TOTAL 136.3M 103.2M 151952 65.4M 48% 10
我省略了不可写区域部分,因为它溢出了堆栈溢出限制 我没有看到任何内存泄漏。以下程序在运行上述函数100.000次前后打印其内存使用情况。这两个数字对我来说都一样
#include <cairo.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define HEIGHT 500
#define WIDTH 500
void draw_with_cairo (cairo_t *cr)
{
PangoLayout *layout;
PangoFontDescription *desc;
int i;
cairo_save (cr);
cairo_scale (cr, 1, -1);
cairo_translate (cr, 0, -HEIGHT);
cairo_translate (cr, 400, 300);
layout = pango_cairo_create_layout (cr);
pango_layout_set_text (layout, "Test", -1);
desc = pango_font_description_from_string ("BMitra 32");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
for (i = 0; i < 12; i++)
{
int width, height;
double angle = i + (360.0 * i) / 12;
double red;
cairo_save (cr);
red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
cairo_set_source_rgb (cr, red, 0, 1.0 - red);
cairo_rotate (cr, angle * G_PI / 180.);
pango_cairo_update_layout (cr, layout);
pango_layout_get_size (layout, &width, &height);
cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - 250);
pango_cairo_show_layout (cr, layout);
cairo_restore (cr);
}
cairo_restore (cr);
g_object_unref (layout);
}
static void print_memory_usage(const char *comment)
{
char buffer[1024];
sprintf(buffer, "grep -E VmPeak\\|VmSize /proc/%d/status", getpid());
printf("Executing %s %s\n", buffer, comment);
system(buffer);
}
int main()
{
cairo_surface_t *s;
cairo_t *cr;
int i;
print_memory_usage("at beginning of main()");
s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
cr = cairo_create(s);
print_memory_usage("after cairo init");
draw_with_cairo(cr);
print_memory_usage("after one iteration");
for (i = 0; i < 100 * 1000; i++)
draw_with_cairo(cr);
print_memory_usage("after loop");
cairo_surface_destroy(s);
cairo_destroy(cr);
print_memory_usage("at end");
return 0;
}
备注:我在最新的debian测试amd64上测试了这个问题。您有没有任何独立的示例可以说明我可以尝试的问题?您使用的是哪种Pango版本?谷歌发现了一个内存泄漏,这显然是在Pango 1.18.2中修复的。我刚刚检查过,Pango-1.38.1。事实上,这是macports的最新版本。我想这是一个未报告的错误。但是经过这么多的搜索,我已经失去了对pango的信任!到处都有很多关于内存泄漏的报告,这在一个结构良好的代码中是不应该的。顺便说一句,我发现内存泄漏发生在pango_cairo_update_布局函数中。所以我猜问题出在pango的mac版本中。我看到了漏洞,这肯定是在例行程序。事实上,我已经指出这是盘古布局。好吧,这是一个艰难的情况,我不打算修改盘古在所有!像上面这样的事情会重现你的问题吗?(在删除/proc魔法后,我想用getrusage()替换它是有意义的)首先,谢谢你教我!我运行了你的代码,并进行了镜像修改。我没有使用/proc magic(如您所说!),而是按如下方式使用vmmap:“vmmap-resident%d | grep TOTAL”。我只是把它涂成灰色,给我总的内存使用量。我将结果附加到问题文本中。再次感谢。
#include <cairo.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define HEIGHT 500
#define WIDTH 500
void draw_with_cairo (cairo_t *cr)
{
PangoLayout *layout;
PangoFontDescription *desc;
int i;
cairo_save (cr);
cairo_scale (cr, 1, -1);
cairo_translate (cr, 0, -HEIGHT);
cairo_translate (cr, 400, 300);
layout = pango_cairo_create_layout (cr);
pango_layout_set_text (layout, "Test", -1);
desc = pango_font_description_from_string ("BMitra 32");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
for (i = 0; i < 12; i++)
{
int width, height;
double angle = i + (360.0 * i) / 12;
double red;
cairo_save (cr);
red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
cairo_set_source_rgb (cr, red, 0, 1.0 - red);
cairo_rotate (cr, angle * G_PI / 180.);
pango_cairo_update_layout (cr, layout);
pango_layout_get_size (layout, &width, &height);
cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - 250);
pango_cairo_show_layout (cr, layout);
cairo_restore (cr);
}
cairo_restore (cr);
g_object_unref (layout);
}
static void print_memory_usage(const char *comment)
{
char buffer[1024];
sprintf(buffer, "grep -E VmPeak\\|VmSize /proc/%d/status", getpid());
printf("Executing %s %s\n", buffer, comment);
system(buffer);
}
int main()
{
cairo_surface_t *s;
cairo_t *cr;
int i;
print_memory_usage("at beginning of main()");
s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
cr = cairo_create(s);
print_memory_usage("after cairo init");
draw_with_cairo(cr);
print_memory_usage("after one iteration");
for (i = 0; i < 100 * 1000; i++)
draw_with_cairo(cr);
print_memory_usage("after loop");
cairo_surface_destroy(s);
cairo_destroy(cr);
print_memory_usage("at end");
return 0;
}
Executing grep -E VmPeak\|VmSize /proc/31881/status at beginning of main()
VmPeak: 76660 kB
VmSize: 76660 kB
Executing grep -E VmPeak\|VmSize /proc/31881/status after cairo init
VmPeak: 77640 kB
VmSize: 77640 kB
Executing grep -E VmPeak\|VmSize /proc/31881/status after one iteration
VmPeak: 79520 kB
VmSize: 79520 kB
Executing grep -E VmPeak\|VmSize /proc/31881/status after loop
VmPeak: 79520 kB
VmSize: 79520 kB
Executing grep -E VmPeak\|VmSize /proc/31881/status at end
VmPeak: 79520 kB
VmSize: 78540 kB