2016-01-26 31 views
0

我在一個測試驅動器應用程序中使用Pango庫,旁邊是開羅,沒有GTK,目前我正在MacOSX上進行編譯。我有一個內存泄漏問題,我已經追查到這個功能:Pango中的內存泄漏

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); 

} 

這個程序被調用了很多,也許百倍第二。內存泄漏很大,3secs大約30MB,並且速度不變。當我比較這段代碼時,對我來說似乎相當好。我已經搜索了這個,在Gtk應用程序中使用pango時發現了許多內存泄漏的引用,並且他們都在pango或gtk中尋找補丁。我真的很困惑,不敢相信在像pango這樣的大量使用的庫中會出現這樣的錯誤,並認爲這是我自己的代碼的問題。任何建議表示讚賞。

這是烏利的代碼的VMMap結果:

Executing vmmap -resident 25897 | grep TOTAL at beginning of main() 
TOTAL       321.3M 126.2M  485 
TOTAL        18.0M  200K  1323  173K  0%  2 
Executing vmmap -resident 25897 | grep TOTAL after cairo init 
TOTAL       331.3M 126.4M  489 
TOTAL        27.0M  224K  1327  1155K  4%  6 
Executing vmmap -resident 25897 | grep TOTAL after one iteration 
TOTAL       383.2M 143.9M  517 
TOTAL        37.2M  3368K  18634  3423K  8%  5 
Executing vmmap -resident 25897 | grep TOTAL after loop 
TOTAL       481.6M 244.1M  514 
TOTAL        137.2M  103.7M  151961  66.4M  48%  6 
Executing vmmap -resident 25897 | grep TOTAL at end 
TOTAL       481.6M 244.1M  520 
TOTAL        136.3M  103.1M  151956  65.4M  48%  11 

這是最後階段的未過濾的輸出:

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 

我省略了不可寫入區域的部分,因爲它是溢出的stackoverflow限制!

+0

您是否有任何自包含的示例顯示我可以嘗試的問題? –

+0

你使用哪個Pango版本?谷歌發現https://bugzilla.gnome.org/show_bug.cgi?id=474708這是一個內存泄漏,顯然是在Pango 1.18.2中修復的。 –

+0

我剛剛檢查了一下,pango-1.38.1。實際上這是macports的最新版本。我想這是一個未報告的錯誤。但在所有這些搜索之後,我失去了對pango的信任!有很多關於內存泄漏的報告,在結構良好的代碼中不應該出現這種情況。 –

回答

1

我沒有看到任何內存泄漏。以下程序在運行上述功能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; 
} 

輸出爲我(沒有任何內存泄漏的痕跡):

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 

P.S .:我測試了這個上了最新的Debian的測試AMD64。

+0

所以我想問題是在pango的mac版本。我看到了泄漏,這絕對是在那個例程中。事實上,我有針指出它是潘戈佈局。 –

+0

好吧,這是一個艱難的情況,我根本不傾向於修改pango! –

+0

像上面那樣重現你的問題? (除去/ proc-magic之後,我想用getrusage()替換它是有道理的) –