Как очистить кучу памяти в esp32

Я использую в своей программе бесплатную RTOS на esp32. Однако в какой-то момент, когда я выполняю xTaskCreate(), он возвращает -1, что означает ошибку could_not_allocate_required_memory. В моей программе каждый раз, когда я вызываю getFreeHeap(), он уменьшается примерно на 2000 и никогда не очищается и не сбрасывается, если его недостаточно или меньше 2000, xTaskCreate возвращает -1.

Прочитав множество форумов, я не смог найти способ очистить память для создания задачи. Может ли кто-нибудь помочь мне в этом?

фрагмент кода

void createTsk(){
  SerialDebug.print("available Heap size: ");
  SerialDebug.println(ESP.getFreeHeap());

  BaseType_t xBy = xTaskCreate(taskPriorityOne, "TaskOne", 20240, NULL, 1, &thOne);
  SerialDebug.println("Return Val : ");
  SerialDebug.println(xBy);
}

void taskPriorityOne(void *paramter)
{
   SerialDebug.println("Prio 1 task Initiated");
   threadTask(priorityOneQue, "task1", thOne);
}

void threadTask(QueueHandle_t priorityQue, String taskName, TaskHandle_t th)
{
  xQueueReceive(priorityQue, &taskdataholder, portMAX_DELAY);
  ongoingProcess = taskdataholder;
  furtherExecutionHttp(taskdataholder, fnm, taskName, th);
}

void furtherExecutionHttp(DataHolder *taskdataholder, String fnm, String 
taskName, TaskHandle_t th)
{
   String response = httpRequest(taskdataholder->protocol, taskdataholder- 
   >host, taskdataholder->port, taskdataholder->url, taskdataholder->body, 
   fnm);

  delay(10);

  free(taskdataholder);
  SerialDebug.println("Releasing memory..\n");

  vTaskDelete(th);
}

, 👍2

Обсуждение

Я мало что знаю о FreeRTOS, но память в куче можно очистить, удалив динамически создаваемые объекты, которые вам не нужны. Вы искали функцию во FreeRTOS для этого? В простом C/C++ это просто оператор удаления., @chrisl

@chrisl привет. Спасибо за ответ. Я использую Arduino IDE, поэтому не могу внести несколько пользовательских модификаций. Можете ли вы предложить какой-нибудь более решенный способ?, @Androing

Я не прошу «индивидуальных модификаций». Код внутри Arduino IDE представляет собой простой C/C++ с платформой Arduino (и в вашем случае с платформой FreeRTOS). У вас есть некоторый код (пожалуйста, отредактируйте его в своем вопросе), и в этом коде вы динамически создаете объекты. Эти объекты необходимо удалить снова. Кто-то должен отслеживать создаваемые объекты и освобождать память, когда они больше не нужны. Это можете быть вы со своим собственным кодом или, может быть, платформа FreeRTOS (о которой я недостаточно знаю, чтобы сказать, способна ли она на это)., @chrisl

Добавлен код @chrisl. пожалуйста, предложите., @Androing

xTaskCreate возвращает указатель. Вы должны освободить его. Когда вы закончите с задачей, вам нужно вызвать xTaskDelete., @PMF

@PMF это написано в методе continueExecutionHttp в конце., @Androing

@Androing: Хм... Верно, выглядит правильно. Однако, поскольку thOne — глобальная переменная, это работает только в том случае, если одновременно выполняется только одна задача. Если вы запустите новую задачу, пока старая не завершилась, следующий вызов xTaskDelete удалит задачу, которая была запущена последней, а не текущую. Попробуйте xTaskDelete(null), чтобы удалить текущую задачу., @PMF

HTTP-ответ составляет около 2 КБ?, @dandavis

@dandavis 700-900 байт, @Androing


2 ответа


0

Вероятно, вам не захочется "очищать" кучу, предполагая, что вы имеете в виду либо освобождение, либо обнуление всей памяти, выделенной из кучи.

Если вы просто вернете всю память в кучу, когда она закончится, в вашем коде могут появиться указатели на эту память, оставшуюся, когда эта память будет выделена для другого использования, а это означает, что некоторые данные, скорее всего, будут перезаписаны. Или, если вы очистите кучу (обнулив ее), вы перезапишете данные, уже хранящиеся там, и, возможно, все равно не сможете выделить больше памяти, если распределитель не «знает»; что вы хотели его вернуть.

Вместо этого ваш код должен освобождать каждое выделение памяти, как только оно перестает быть полезным, и следить за тем, чтобы указатель на эту память не использовался снова. Один из способов защитить повторное использование мертвых указателей: 1) обнулить их при освобождении памяти, на которую они указывают; и 2) всегда проверяйте действительный указатель (ненулевой), прежде чем пытаться его использовать.

,

2

Куча памяти в ESP32 не может быть очищена явно. Память кучи используется для хранения динамически выделяемых объектов, и когда объект больше не нужен, он автоматически освобождается сборщиком мусора.

Вы можете освободить часть памяти кучи, удалив неиспользуемые объекты. В своем коде вы создаете новый объект с именем taskdataholder в функции furtherExecutionHttp(). Этот объект выделяется в куче и будет освобожден только после завершения функции. Если вы хотите освободить эту память, вы можете вызвать функцию free() до того, как функция вернется.

,