rogchap / v8go

Execute JavaScript from Go

Home Page:https://rogchap.com/v8go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OOM after multiple calls (mac air M1) (go1.21.4 darwin/arm64)

loadgame opened this issue · comments

main.go

package main

import (
	"log/slog"
	"runtime"

	"rogchap.com/v8go"
)

var ctx *v8go.Context

func runJavascript(script string) string {
	val, err := ctx.RunScript(script, "test.js")
	if err != nil {
		slog.Error("error", "val", val, "err", err)
	}
	return val.String()
}

func main() {
	ctx = v8go.NewContext()
	defer ctx.Close()
	runJavascript(`

		function test(jsonStr) {
			var jsonObj = JSON.parse(jsonStr);
			jsonObj.type = "test"
			var jsonStr = JSON.stringify(jsonObj);
			return jsonStr;
		}

	`)
	var res string
	for i := 0; i < 100000000; i++ {
		res = runJavascript(`test('{"value":"empty"}')`)
		if i%1000000 == 0 {
			slog.Warn("TestVM & golang GC", "res", res, "i", i)
			runtime.GC()
		}
	}
}

log below


023/11/15 20:25:22 WARN TestVM & golang GC res="{\"value\":\"empty\",\"type\":\"test\"}" i=18000000

<--- Last few GCs --->

[85430:0x130008000]    93664 ms: Mark-Compact 1377.1 (1442.6) -> 1363.5 (1445.1) MB, 801.6 / 0.0 ms  (average mu = 0.335, current mu = 0.213) allocation failure; scavenge might not succeed
[85430:0x130008000]    95239 ms: Mark-Compact 1380.9 (1446.6) -> 1367.5 (1449.1) MB, 1315.9 / 0.0 ms  (average mu = 0.239, current mu = 0.164) allocation failure; scavenge might not succeed


<--- JS stacktrace --->


#
# Fatal javascript OOM in Reached heap limit
#

SIGTRAP: trace trap
PC=0x104e36750 m=8 sigcode=0
signal arrived during cgo execution

goroutine 1 [syscall]:
runtime.cgocall(0x104e156b0, 0x1400005fcd8)
        /usr/local/go/src/runtime/cgocall.go:157 +0x44 fp=0x1400005fca0 sp=0x1400005fc60 pc=0x104d5f0f4
rogchap.com/v8go._Cfunc_ValueToString(0x37889ea80)
        _cgo_gotypes.go:2173 +0x3c fp=0x1400005fcd0 sp=0x1400005fca0 pc=0x104e107cc
rogchap.com/v8go.(*Value).String.func1(0x1400005fe08?)
        /Users/peter/go/pkg/mod/rogchap.com/v8go@v0.9.0/value.go:242 +0x60 fp=0x1400005fd70 sp=0x1400005fcd0 pc=0x104e12840
rogchap.com/v8go.(*Value).String(0x1400000e030?)
        /Users/peter/go/pkg/mod/rogchap.com/v8go@v0.9.0/value.go:242 +0x2c fp=0x1400005fe10 sp=0x1400005fd70 pc=0x104e126bc
main.runJavascript({0x105cce45d?, 0x19?})
        /vm_oom/main.go:17 +0xc4 fp=0x1400005fe90 sp=0x1400005fe10 pc=0x104e13114
main.main()
        /vm_oom/main.go:37 +0xc0 fp=0x1400005ff30 sp=0x1400005fe90 pc=0x104e13200
runtime.main()
        /usr/local/go/src/runtime/proc.go:267 +0x2bc fp=0x1400005ffd0 sp=0x1400005ff30 pc=0x104d9188c
runtime.goexit()
        /usr/local/go/src/runtime/asm_arm64.s:1197 +0x4 fp=0x1400005ffd0 sp=0x1400005ffd0 pc=0x104dbe784



This seems to fix the issue

func runJavascript(script string) string {
	val, err := ctx.RunScript(script, "test.js")
	defer val.Release() // <= release the value
	if err != nil {
		slog.Error("error", "val", val, "err", err)
	}
	return val.String()
}