This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

What could cause heap out of memory problem?

Other Parts Discussed in Thread: SYSBIOS

Hi,

I am new to SYS/BIOS. After I import example project 'memory_EK_TM4C1294XL_TI_TivaTM4C1294NCPDT' to TM4C1294 LaunchPad, I want to to add a task to the project. task1 is dynamic created task. Then, I add a similar task (task3) to task1 to the project. When either one (task1 or task3) is in the project, either one works as the original example project. When both are in the project, it has an exception error:

ti.sysbios.heaps.HeapMem: line 307: out of memory: handle=0x20006618, size=2048
xdc.runtime.Error.raise: terminating execution

I don't know what is the problem. It perhaps does not allow two tasks to create its respective heap memory? I don't know yet. I would give more info about the project.

task1:

#define TASK1BUFSIZE0   128      /* size of allocation */
#define TASK1BUFSIZE1   64       /* size of allocation */
#define TASK1BUFSIZE2   32       /* size of allocation */
#define TASK1BUFSIZE3   16       /* size of allocation */
#define TASK1NUMBUFS    4        /* number of buffers */


Void task1Fxn(UArg arg0, UArg arg1)
{
    Ptr bufs[TASK1NUMBUFS];
    IHeap_Handle heap = HeapMem_Handle_upCast(task1Heap);

    System_printf("Initial task1 heap status\n");

    /* print initial task1Heap status */
    printHeapStats(heap);

    bufs[0] = Memory_alloc(heap, TASK1BUFSIZE0, 0, NULL);

    bufs[1] = Memory_alloc(heap, TASK1BUFSIZE1, 0, NULL);

    bufs[2] = Memory_alloc(heap, TASK1BUFSIZE2, 0, NULL);

    Memory_free(heap, bufs[1], TASK1BUFSIZE1);
    Memory_free(heap, bufs[2], TASK1BUFSIZE2);

    bufs[3] = Memory_alloc(heap, TASK1BUFSIZE3, 0, NULL);

    Memory_free(heap, bufs[0], TASK1BUFSIZE0);
    Memory_free(heap, bufs[3], TASK1BUFSIZE3);

    System_printf("Final task1 heap status\n");

    /* print task1Heap status */
    printHeapStats(heap);

    System_printf("Task1 Complete\n");
}
......
#define TASK3BUFSIZE0   32      /* size of allocation */
#define TASK3BUFSIZE1   4       /* size of allocation */
#define TASK3BUFSIZE2   4       /* size of allocation */
#define TASK3BUFSIZE3   4       /* size of allocation */
#define TASK3NUMBUFS    4        /* number of buffers */

Void task3(UArg arg0, UArg arg1)
{
    Ptr bufs[TASK3NUMBUFS];
    IHeap_Handle heap = HeapMem_Handle_upCast(task2heap);

    System_printf("Initial TASK3 heap status\n");

    /* print initial TASK3Heap status */
    printHeapStats(heap);

    bufs[0] = Memory_alloc(heap, TASK3BUFSIZE0, 0, NULL);

    bufs[1] = Memory_alloc(heap, TASK3BUFSIZE1, 0, NULL);

    bufs[2] = Memory_alloc(heap, TASK3BUFSIZE2, 0, NULL);

    Memory_free(heap, bufs[1], TASK3BUFSIZE1);
    Memory_free(heap, bufs[2], TASK3BUFSIZE2);

    bufs[3] = Memory_alloc(heap, TASK3BUFSIZE3, 0, NULL);

    Memory_free(heap, bufs[0], TASK3BUFSIZE0);
    Memory_free(heap, bufs[3], TASK3BUFSIZE3);

    System_printf("Final TASK3 heap status\n");

    /* print TASK3Heap status */
    printHeapStats(heap);

    System_printf("TASK3 Complete\n");
}
...........
Int main()
{
    /* Call board init functions */
    Board_initGeneral();

    Task_create(task1Fxn, NULL, NULL);
    Task_create(task3, NULL, NULL);

Is there some restriction I break in the above code?

Thanks,

  • Here is a screen shot.

    Whether is it helpful to find the problem?

    Thanks,

  • Hi Robert,

    I am suspecting that the BIOS system heap is not big enough for creating a 3rd task. The system heap is used whenever an object is created. For example, when you dynamically create a task, a task object (and possibly the task's stack) gets allocated on the system heap.

    Can you try increasing the BIOS heap size by updating the below line in your project's *.cfg script ?

    BIOS.heapSize = <new heap size>;

    Best,

    Ashish

  • Hi,

    When I increase heap to:

    BIOS.heapSize = 8192*4;

    it does solve the error problem. My concern is that TM4C1294 has not very large RAM (256KB). The above heap size looks large?

    Furthermore, I supposed that task1 allocates memory first, then it frees the memory. task3 will do the same thing of task1 (allocate and free memory). It should not demand more heap than task1 alone.

    There is a possibility that task3 and task1 have different priorities. One task can preempt the other before the second task frees the memory, but I do not see the priorities explicitly yet. It give me more work to check on their priorities now.

    Could you explain my above concerns ? Thanks,

  • I still want to know which row in ROV/HeapMem corresponds to which task's memory. 

    For the increased heap size 

    BIOS.heapSize = 8192*4;

    it looks like the largest memory block is for task0 (which creates memory HeapBuf), as the first two rows are like task1 and task3 for its obvious 4 times relationship.

    The total free size of last row is smaller than its total size. Does it means memory leak? although I don't see any leak possibilities there. Thanks

  • Excuse me. I would like to rephrase my question here.

    I suppose heap is shared with all tasks. Is it right? 

    Then, if two separate tasks allocate heap, first of all, is it allowed to do so?

    If the answer is yes, then, for two tasks having the same priority, same memory requirement(size), what size should be for two tasks comparing with for one task?

    Logically, it sounds like two tasks do not require heap size doubled if the two tasks run sequentially. But I find that I have to increase heap size for two tasks than for one task. Are there something wrong in the above description?

    Thanks,

  • Hi Robert,

    Let me try to explain how the memory management works in the default (unmodified) Memory example. I think it will help you better understand how to manage the heap sizes.

    In the Memory example, 3 heaps are involved. The first one is the BIOS or system heap. There is no explicit create for this heap in the example, it is created internally by the kernel. You can control the size and placement of this heap (size controlled by setting BIOS.heapSize). This heap is used for allocating space for dynamically created objects like the Task object, Semaphore object, etc. When you call Task_create, a task object is allocated on this heap and if you use the default task params (which the example does) then a stack is also allocated on the system heap for the newly created task. Creating a task consumes heap memory and this memory is not going to be released until the task is deleted (which is not being done in the Memory example). So, if you create extra tasks by modifying the example, you need to also increase the system heap size so there is enough space to allocate an extra task object and stack.

    The second heap in the example is task0's heap. This heap uses a different heap manager called HeapBuf (unlike the system heap which uses HeapMem by default) and its details can be viewed through the "HeapBuf" ROV view. The Memory_alloc and free inside the task0Fxn is performed on this heap.

    The third heap in the example is task1's heap. This heap uses HeapMem. The memory alloc/free code in task1Fxn is performed on this heap. As you can now tell, task0 and task1 dont share the heap, they have their own heaps and therefore if the alloc/free functions in task0Fxn and task1Fxn are interleaved due to task switching, there is no possibility of running out of memory.

    Hope this helps.

    Best,
    Ashish
  • Thank you, Ashish. Your post answers some of my questions. One key question is after I created another task, which is almost copied from task1. Here is the code:

    #define TASK3BUFSIZE0   32/DIV2MEM      /* size of allocation */
    #define TASK3BUFSIZE1   16/DIV2MEM       /* size of allocation */
    #define TASK3BUFSIZE2   8/DIV2MEM       /* size of allocation */
    #define TASK3BUFSIZE3   4/DIV2MEM       /* size of allocation */
    #define TASK3NUMBUFS    4        /* number of buffers */
    
    Void main3(UArg arg0, UArg arg1)
    {
        Ptr bufs[TASK3NUMBUFS];
    
        IHeap_Handle heap = HeapMem_Handle_upCast(task2Heap);
    
        System_printf("Initial TASK3 heap status\n");
    
        /* print initial TASK3Heap status */
        printHeapStats(heap);
    
        bufs[0] = Memory_alloc(heap, TASK3BUFSIZE0, 0, NULL);
    
        bufs[1] = Memory_alloc(heap, TASK3BUFSIZE1, 0, NULL);
    
        bufs[2] = Memory_alloc(heap, TASK3BUFSIZE2, 0, NULL);
    
        Memory_free(heap, bufs[1], TASK3BUFSIZE1);
        Memory_free(heap, bufs[2], TASK3BUFSIZE2);
    
        bufs[3] = Memory_alloc(heap, TASK3BUFSIZE3, 0, NULL);
    
        Memory_free(heap, bufs[0], TASK3BUFSIZE0);
        Memory_free(heap, bufs[3], TASK3BUFSIZE3);
    
        System_printf("Final TASK3 heap status\n");
    
        /* print TASK3Heap status */
        printHeapStats(heap);
    
        System_printf("TASK3 Complete\n");
    }
    
    Even though I make both task1 and this task (main3) heap size in half (thus, the combined heap size should be the same of the previous task1), it generates out of memory exception error (which results in project earlier terminating). I have check that both task1 and main3 task have the same priority, i.e. both should run without preemption.
    
    What is an explanation about the question?
    Thanks again. 

  • Thank you. After carefully reading your answer, it solves all my questions now.
  • Excuse me. I just find that there is a small difference from what you describe and what I see with ROV.

    For the original imported project, It is seen that there are two items of HeapMem on ROV. Here is it:

    It is not the three heap as in your post. Does the task1 heap use the same heap with the system heap? It looks like in this way.

    After I add another task, which is almost copied from task1, but has separate heap creation and memory allocation. Now it has three items in HealMem on ROV. It looks like the new task heap uses a new heap, even though it is the same HeapMem type.

    Can only one task share HeapMem with system heap?

    Thanks,

  • Hi Robert,

    Robert William said:

    It is not the three heap as in your post. Does the task1 heap use the same heap with the system heap? It looks like in this way.

    The third heap I was referring to uses a different heap manager (Uses HeapBuf). You are looking at HeapMem module view in ROV. If you look at the HeapBuf module view, you will see the third heap (HeapBuf is right above HeapMem in the "Viewable Modules" list in ROV).

    Best,

    Ashish