Closed5
TinyGo で メモリの使いすぎによるエラーが出た際の対処法をまとめる

現象:TinyGo のプログラムをマイコンボードに書き込み、動かした結果、以下のエラーが発生した。
panic: runtime error at 0x????????: out of memory
[tinygo: panic at *.go:??:??]
(?→数値、*→文字列)

対処1:大きなデータを格納する際、バッファとしてスライスを使用している場合は global 変数の配列を使用するようにする。
ループ内でスライスを定義している場合などでは、都度メモリが割り当てられ、Heap に積まれるため。
補足:tinygo buildコマンドで--print-allocs .
を付けて実行すると heap allocs している個所の一覧が表示されるため、該当箇所を減らすと良さそう。
追記: 2024/12/14

対処2:大きなデータを扱う場合は、そもそも必要なデータだけ扱うようにする。
以下、例。
- 自分が使っていた API(Open Weather API 3.0) では 不要な情報を省くパラメーターを指定することができる。
- 参考:https://openweathermap.org/api/one-call-3#current → 「exclude」
- API から JSON データを取得して Unmarshal する場合、データを受け取る構造体のメンバ変数はすべてのデータ分を定義する必要はないため、減らすことを検討する
- 参考:https://pkg.go.dev/encoding/json#Unmarshal
- 具体例としては下記参照
デフォルトの構造体
type AutoGenerated struct {
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
Timezone string `json:"timezone"`
TimezoneOffset int `json:"timezone_offset"`
Hourly []struct {
Dt int `json:"dt"`
Temp float64 `json:"temp"`
FeelsLike float64 `json:"feels_like"`
Pressure int `json:"pressure"`
Humidity int `json:"humidity"`
DewPoint float64 `json:"dew_point"`
Uvi int `json:"uvi"`
Clouds int `json:"clouds"`
Visibility int `json:"visibility"`
WindSpeed int `json:"wind_speed"`
WindDeg int `json:"wind_deg"`
WindGust float64 `json:"wind_gust"`
Weather []struct {
ID int `json:"id"`
Main string `json:"main"`
Description string `json:"description"`
Icon string `json:"icon"`
} `json:"weather"`
Pop float64 `json:"pop"`
Rain struct {
OneH float64 `json:"1h"`
} `json:"rain,omitempty"`
} `json:"hourly"`
}
変更後の構造体
// 不要なデータは削除。Hourly はデフォルトで 48h 分取得してしまうが 6h 分に限定した。
type WeatherJSON struct {
Timezone string `json:"timezone"`
TimezoneOffset int `json:"timezone_offset"`
Hourly [6]struct {
Dt int `json:"dt"`
Weather []struct {
Icon string `json:"icon"`
} `json:"weather"`
} `json:"hourly"`
}

メモしておきたいことは書いたため、一旦 close する。

現象:TinyGo のプログラムをマイコンボードに書き込み、動かした結果、エラーは発生していないが、処理が止まってしまった。
対策:encoding/json の処理等 reflect パッケージを使用している処理は、スタックを使う量が多いため、 build 時に --stack-size
オプションをつけて、スタックサイズを調整すると改善する場合がある。
このスクラップは2024/11/29にクローズされました