rogchap / v8go

Execute JavaScript from Go
https://rogchap.com/v8go
BSD 3-Clause "New" or "Revised" License
3.19k stars 213 forks source link

Limit memory of context #308

Open danthegoodman1 opened 2 years ago

danthegoodman1 commented 2 years ago

It would be extremely useful to be able to limit the memory usage of a context so that it cannot exceed some limit (and that we can also view how much was used, but I believe that is already possible).

Maybe a hack to work around this would be to poll the Isolate.GetHeapStatistics(), but that does not allow for fast respone to large memory usage.

danthegoodman1 commented 2 years ago

Maybe if there was a way to pass in the max_heap_size flag?

mustafaakin commented 1 year ago

This works for limiting memory:

v8.SetFlags("--max-heap-size=32 --initial-heap-size=2")

However it sets for all contexts. We use 1 context per process for increased security but I believe it won't be enough for all.

danthegoodman1 commented 1 year ago

@mustafaakin all contexts as in shared or that is the limit for each individual context?

mustafaakin commented 1 year ago

I believe it's global, shared all.

Flags are here:

https://github.com/v8/v8/blob/5fe0aa3bc79c0a9d3ad546b79211f07105f09585/src/flags/flag-definitions.h#L1163

Or

https://gist.github.com/andrewiggins/68c3165d47769a39eb5ae16e3001d6c6

isolated-vm project has a configurable limit per isolate:

https://github.com/laverdet/isolated-vm/blob/9a3defebf80f4396290c608d7d3eabb1f95da92f/isolated-vm.d.ts#L137

It passes the following:

https://github.com/laverdet/isolated-vm/blob/9a3defebf80f4396290c608d7d3eabb1f95da92f/src/module/isolate_handle.cc#L113

I believe the Isolate* iso = Isolate::New(params); function can be replaced with auto holder = IsolateEnvironment::New(memory_limit, std::move(snapshot_blob), snapshot_blob_length); somehow but neither my C or CGO is good enough to implement it.

https://github.com/rogchap/v8go/blob/cee5f84bb54338bdef150b3e43daace4669c5de2/v8go.cc#L154

danthegoodman1 commented 1 year ago

@mustafaakin thanks for the pointers! I'm not very fluent in CGO either nor v8 specifically so I'd be treading dangerous waters playing in there. Haven't had the time to tinker on my own, perhaps I should find someone fluent enough to bother :)

I'd love to make it per isolate and or context so I can limit time and memory, right now I am coupling golang and isolated-vm to handle this.

bjg2 commented 8 months ago

Not sure I understand the proposed solution, I tried limiting memory through flag (I have set the flag "--max-heap-size 16") and got exception in cgo, which I cannot recover from in go:

<--- Last few GCs --->

[1:0x7f51ef55c5e0]    40374 ms: Mark-Compact (reduce) 28.3 (29.1) -> 17.1 (17.9) MB, 254.7 / 0.0 ms  (average mu = 0.498, current mu = 0.408) allocation failure; scavenge might not succeed

<--- JS stacktrace --->

#
# Fatal javascript OOM in Reached heap limit
#

SIGTRAP: trace trap
PC=0xdf4076 m=20 sigcode=128
signal arrived during cgo execution