Closed4
TinyGo で メモリの使いすぎによるエラーが出た際の対処法をまとめる
現象:TinyGo のプログラムをマイコンボードに書き込み、動かした結果、以下のエラーが発生した。
panic: runtime error at 0x????????: out of memory
[tinygo: panic at *.go:??:??]
(?→数値、*→文字列)
対処1:大きなデータを格納する際、バッファとしてスライスを使用している場合は global 変数の配列を使用するようにする。
ループ内でスライスを定義している場合などでは、都度メモリが割り当てられ、Heap に積まれるため。
補足:tinygo buildコマンドで--print-allocs .
を付けて実行すると heap allocs している個所の一覧が表示されるため、該当箇所を減らすと良さそう。
対処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 する。
このスクラップは1ヶ月前にクローズされました