Closed wamisnet closed 8 years ago
推定原因: loop()の中の DataElement a = DataElement(); aが解放できてないかも。
対策案 ① Finalize()呼ぶ案 https://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
#include "src/AzureIoTHub.h"
void setup() {
Serial.begin(115200);
WiFi.begin("SSID", "PASS");
Azure.begin(IoTHub, "Your Key"); //YourKey Example:"HostName=YourHost.azure-devices.net;DeviceId=YourDevice;SharedAccessKey="
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
Serial.println("push");
DataElement a = DataElement();
a.setValue("set", 120);
Azure.push(&a);
Serial.println("pushed");
a. Finalize(); // ★ add
delay(5000);
} else {
Serial.println("Not connected to the Internet");
delay(250);
}
}
②aをグローバルにする案
#include "src/AzureIoTHub.h"
DataElement a; // ★ add
void setup() {
Serial.begin(115200);
WiFi.begin("SSID", "PASS");
Azure.begin(IoTHub, "Your Key"); //YourKey Example:"HostName=YourHost.azure-devices.net;DeviceId=YourDevice;SharedAccessKey="
a = DataElement(); // ★ add
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
Serial.println("push");
// DataElement a = DataElement(); // ★ del
a.setValue("set", 120);
Azure.push(&a);
Serial.println("pushed");
delay(5000);
} else {
Serial.println("Not connected to the Internet");
delay(250);
}
}
①については未対応ですが、②についてはクラッシュしてしまい、実行することができませんでした。 グローバル変数についてはあまりよいとは思いません。インスタンスを立てるタイミングで内容が消えるので今の書き方のほうが良いと思います。
Azure.push(&a);という表記を少々変更して仮にAzure.push();とした場合メモリはかわりませんでした。
IoTHub.cpp内の46行のbytesWritten = tlsClient.print(buildHttpRequest(data->toCharArray()));
data->toCharArray() この処理が主にメモリの変化をさせている
了解。見てみます。
https://github.com/interactive-matter/aJson/issues
このライブラリーを使っているのですが、メモリリークが起こってるようです…
予想でしかないけど、気になったのは以下。 ①data->toCharArray()が返してる物が解放できていない?
これだとしたら。。 https://github.com/interactive-matter/aJson/issues/39
char* json = aJson.print(root);
Serial.println(json);
free(json);
bytesWritten = tlsClient.print(buildHttpRequest(data->toCharArray()));
↓
char* charArray = data->toCharArray();
bytesWritten = tlsClient.print(buildHttpRequest(charArray));
free(charArray);
②read漏れしている? 違うかもしれませんが。
do {
if (tlsClient.connected()) {
yield();
chunk = tlsClient.readStringUntil('\n');
response += chunk;
}
chunk = ""; // これが必要?
} while (chunk.length() > 0 && ++limit < 100);
やっぱり環境作らないと、関数がどのライブラリの関数かわからないので、リファレンスも探せないので、環境作ってみますー。
②は違うね。無視して。 切断してたら、カウントアップして抜けるコードだね。
WiFiClientSecureとbuildHttpRequest()が何のライブラリの物かがわかれば(リファレンスがわかれば)もうちょっと調べられます。
①ですね。 https://github.com/wamisnet/Azure-iothub-eventhub-esp8266/blob/master/src/aJson/aJSON.cpp の #572。
char* outBuf = (char*) malloc(PRINT_BUFFER_LEN); /* XXX: Dynamic size. */
matsujirushiさん 原因箇所の特定ありがとうございます。 ここのようですね。
wamisnetさん 修正内容確認しましたが、もしかしたら動かないかも?と思いました。
out = outBuf;
free(outBuf);
return out;
outとoutBufは同じアドレスを指していて、free()しているので保証されないのでは?
①data->toCharArray()が返してる物が解放できていない?
の対策案で対策するのが正解と思われます。
ESP8266で動かした時のSerial表示を上げておく
現状メモリーの空き領域がどんどん減っていっているのでその対策をしたい。