[SOLVED] [memory leak] [master branch] I face a problem when call lv_label_set_text() function periodicity to refresh date

You can use lv_task

lv_task_create(time_refresh, 1000, LV_TASK_PRIO_MID, (void *)(clock));

I face a memory leak problem

Are you calling lv_label_create each time as well? Normally, lv_label_set_text shouldn’t cause memory leaks.

call periodicity in a timer

You must never call LittlevGL functions from an interrupt or another thread unless you guarantee lv_task_handler is not executing at the same time. The only exception to that rule is lv_tick_inc, which is designed to handle the concurrency.

1 Like

HI, I use the demo from github esp32_ili9341

To make a diagnosis of memory consumption, I add memory print periodically.

I enable LV_MEM_CUSTOM, and define a function lv_malloc alloc memory from external RAM.

Then I create a timer to deal lv_task_handler every 5 ms but it’s weird when lv_task_handler was called 2 times later, the memory will consume 100K ram too much.

Don’t know where that 100k+ memory were alloced.

void app_main()
{
    print_memory();
    lv_init();
    print_memory();

    disp_spi_init();
    ili9341_init();
    print_memory();

    lv_disp_drv_t disp;
    lv_disp_drv_init(&disp);
    disp.disp_flush = ili9341_flush;
    disp.disp_fill = ili9341_fill;
    lv_disp_drv_register(&disp);
    print_memory();

    esp_register_freertos_tick_hook(lv_tick_task);
    print_memory();

    helloworld();
    print_memory();

    lv_timer_init();
    print_memory();
    vTaskDelete(NULL);
}

static void helloworld(void)
{
    lv_obj_t * label1 =  lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(label1, "Hello world!");
    lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);
}

static void print_memory(void)
{
    printf("Memory,total:%d, inter:%d, spram:%d, Dram:%d,  %d\r\n", esp_get_free_heap_size(),
       heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_32BIT),
       heap_caps_get_free_size(MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT),
       heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT), print_cnt++);
}

Can you print the allocated sizes in your lv_malloc?

sure, every malloc I have print the size, address.

Memory,total:4399060, inter:366984, spram:4116888, Dram:295740, 0
lv_mem_alloc, size:76, addr:3f812e60
lv_mem_alloc, size:28, addr:3f812eb4
lv_mem_alloc, size:28, addr:3f812ed8
lv_mem_alloc, size:68, addr:3f812efc
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
lv_mem_alloc, size:68, addr:3f812f48
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
lv_mem_alloc, size:68, addr:3f812f94
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
Info: lv_init ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #115)
Memory,total:4398500, inter:366808, spram:4116504, Dram:295564, 1
ILI9341 initialization.
Enable backlight.
Memory,total:4398136, inter:367296, spram:4116504, Dram:296052, 2
lv_mem_alloc, size:28, addr:3f812fe0
Memory,total:4398100, inter:367296, spram:4116468, Dram:296052, 3
Memory,total:4398100, inter:367296, spram:4116468, Dram:296052, 4
lv_mem_alloc, size:68, addr:3f813004
lv_mem_alloc, size:28, addr:3f813050
lv_mem_alloc, size:8, addr:3f813074
Info: label created (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_objx/lv_label.c #133)
lv_mem_alloc, size:16, addr:3f813074
Memory,total:4397964, inter:367296, spram:4116332, Dram:296052, 5
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 6
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 7
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 8
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 9
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 10

total 484 = 76+28+28+68+68+68+28+68+28+8+16
This does not match the memory which were alloced, I want to trace them. Only display hellworld could not need that huge memory.

PS,I use double vdb bufer.
#define LV_VDB_ADR 0X3FBED400
#define LV_VDB2_ADR 0X3FBF6A00

I also add print at lv_mem_alloc.c , here.

#if LV_ENABLE_GC == 1 /*gc must not include header*/
    alloc = LV_MEM_CUSTOM_ALLOC(size);
#else /* LV_ENABLE_GC */
    /*Allocate a header too to store the size*/
    alloc = LV_MEM_CUSTOM_ALLOC(size + sizeof(lv_mem_header_t));
if (alloc != NULL) {
    ((lv_mem_ent_t *) alloc)->header.d_size = size;
    ((lv_mem_ent_t *) alloc)->header.used = 1;
    alloc = &((lv_mem_ent_t *) alloc)->first_data;
}
    printf("%s, size:%d, addr:%x\r\n", __func__, size, (uint32_t)alloc);
#endif /* LV_ENABLE_GC */
#endif /* LV_MEM_CUSTOM */

The problem is I can’t trace the memory here in the picture. It not malloc from my function(lv_mem) , please give a advice.

Selection_012

Please ignore above two post, here is real.
my_lv_malloc is my malloc function.
lv_mem_alloc is the lvgl malloc function.

Memory,total:4399060, inter:366984, spram:4116888, Dram:295740, 0
my_lv_malloc, size:80, addr:3f812e5c
lv_mem_alloc, size:76, addr:3f812e60
my_lv_malloc, size:32, addr:3f812eb0
lv_mem_alloc, size:28, addr:3f812eb4
my_lv_malloc, size:32, addr:3f812ed4
lv_mem_alloc, size:28, addr:3f812ed8
my_lv_malloc, size:72, addr:3f812ef8
lv_mem_alloc, size:68, addr:3f812efc
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
my_lv_malloc, size:72, addr:3f812f44
lv_mem_alloc, size:68, addr:3f812f48
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
my_lv_malloc, size:72, addr:3f812f90
lv_mem_alloc, size:68, addr:3f812f94
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
Info: lv_init ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #115)
Memory,total:4398500, inter:366808, spram:4116504, Dram:295564, 1
ILI9341 initialization.
Enable backlight.
Memory,total:4398136, inter:367296, spram:4116504, Dram:296052, 2
my_lv_malloc, size:32, addr:3f812fdc
lv_mem_alloc, size:28, addr:3f812fe0
Memory,total:4398100, inter:367296, spram:4116468, Dram:296052, 3
Memory,total:4398100, inter:367296, spram:4116468, Dram:296052, 4
my_lv_malloc, size:72, addr:3f813000
lv_mem_alloc, size:68, addr:3f813004
my_lv_malloc, size:32, addr:3f81304c
lv_mem_alloc, size:28, addr:3f813050
my_lv_malloc, size:12, addr:3f813070
lv_mem_alloc, size:8, addr:3f813074
Info: label created (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_objx/lv_label.c #133)
my_lv_malloc, size:20, addr:3f813070
lv_mem_alloc, size:16, addr:3f813074
Memory,total:4397964, inter:367296, spram:4116332, Dram:296052, 5
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 6
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 7
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 8
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 9
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 10

I find when call lv_task_handler(); in a timer,after twice , then memory droped.

here is:

Memory,total:4397964, inter:367296, spram:4116332, Dram:296052, 5
Memory,total:4244312, inter:213644, spram:4116332, Dram:142400, 6

If annotation lv_task_handler , then memory print result is good.

Memory,total:4399076, inter:367004, spram:4116888, Dram:295756, 0
lv_mem_alloc, size:76, addr:3f812e60
lv_mem_alloc, size:28, addr:3f812eb4
lv_mem_alloc, size:28, addr:3f812ed8
lv_mem_alloc, size:68, addr:3f812efc
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
lv_mem_alloc, size:68, addr:3f812f48
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
lv_mem_alloc, size:68, addr:3f812f94
Info: Screen create ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #196)
Info: lv_init ready (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_core/lv_obj.c #115)
Memory,total:4398516, inter:366828, spram:4116504, Dram:295580, 1
ILI9341 initialization.
Enable backlight.
Memory,total:4398152, inter:367316, spram:4116504, Dram:296068, 2
lv_mem_alloc, size:28, addr:3f812fe0
Memory,total:4398116, inter:367316, spram:4116468, Dram:296068, 3
Memory,total:4398116, inter:367316, spram:4116468, Dram:296068, 4
lv_mem_alloc, size:68, addr:3f813004
lv_mem_alloc, size:28, addr:3f813050
lv_mem_alloc, size:8, addr:3f813074
Info: label created (/workshop/audio/experiment/esp32_ili9341/lvgl/lv_objx/lv_label.c #133)
lv_mem_alloc, size:16, addr:3f813074
Memory,total:4397980, inter:367316, spram:4116332, Dram:296068, 5
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 6
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 7
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 8
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 9
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 10
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 11
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 12
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 13
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 14
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 15
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 16
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 17
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 18
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 19
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 20
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 21
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 22
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 23
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 24
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 25
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 26
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 27
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 28
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 29
Memory,total:4397944, inter:367280, spram:4116332, Dram:296032, 30

Is there anything else that uses the external RAM? Maybe something overwrites dynamic memory area.

What if you call lv_task_handler in a task? BTW, why do you need to do it in a timer?

I think lv_task_handler() should be called periodicity,so I set it into a timer, anyway or it in a task while(1) loop is the same. right?

while(1) {
	vTaskDelay(1);
	lv_task_handler();
}

Please make sure you are not calling lv_task_handler concurrently with any function besides lv_tick_inc.

What does that means? My code is simple it’s the github demo( littlevgl/ esp32_ili9341), Do we have test the external RAM usage?

You means do not call lv_task_handler & lv_tick_inc function at the same time?

You cannot call them in the same loop:

/* WRONG */
while(1)
{
    lv_task_handler();
    lv_tick_inc(10);
    sleep_ms(10);
}

But you can use an interrupt/timer/different thread:

void timer_interrupt(void)
{
    lv_tick_inc(10); /* if the timer fires every 10 milliseconds */
}
. . .
while(1)
{
    lv_task_handler();
    sleep_ms(10);
}

I remember we already have found that several times that it can cause issues but I don’t know why. Do you have any ideas? It can mess up timing but should work in theory.

I can’t remember the exact symptoms either. :wink: I think it had something to do with input not being received.

Hmm, that would make sense. However, it shouldn’t cause crash.

@TemcoHeng

It should be fine.

I’ve never tried lv_task_handler() with a timer but tried with a task. They should be same but who knows… So at the end of app_main please try:

while(1)
{
   lv_task_handler();
   vTaskDelay(1);
}

I have find the reason, here.

spi_bus_config_t buscfg = {
    .miso_io_num = -1,
    .mosi_io_num = DISP_SPI_MOSI,
    .sclk_io_num = DISP_SPI_CLK,
    .quadwp_io_num = -1,
    .quadhd_io_num = -1,
    .max_transfer_sz = LV_VDB_SIZE * 2,
};

.max_transfer_sz = LV_VDB_SIZE * 2,

When first call spi_device_queue_trans(), It will malloc TX & RX DMA buffer(size = max_transfer_sz), will cost 150K internal DRAM.

Ah, glad to hear that you found it! :wink: