Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

+hmaxib double counting referenced binary #8871

Open
zzydxm opened this issue Sep 30, 2024 · 3 comments
Open

+hmaxib double counting referenced binary #8871

zzydxm opened this issue Sep 30, 2024 · 3 comments
Assignees
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM

Comments

@zzydxm
Copy link
Contributor

zzydxm commented Sep 30, 2024

We currently use +hmaxib to avoid one too big process crashing the service. But referenced binary will be double counted binary vheap, even when the entire calculation is inside the process, for example, this will crash:

erl +hmax 1000000000 +hmaxib true
Erlang/OTP 26 [erts-14.2.1] [source-b6184975a6] [64-bit] [smp:72:72] [ds:72:72:10] [async-threads:1] [jit:ns] [systemtap]
Eshell V14.2.1 (press Ctrl+G to abort, type help(). for help)
1> B= <<0:100000000>>,ok.
ok
2> C=[B||N<-lists:seq(1,10000)],ok.
ok
*** ERROR: Shell process terminated! ***

In OTP 27, maybe more things are "correctly" counted into binary vheap, for example ets:insert/lookup. Which makes even more double counting and much easier to make process get killed:

erl +hmax 1000000000 +hmaxib true
Erlang/OTP 27 [erts-15.1] [source-caa6a847de] [64-bit] [smp:72:72] [ds:72:72:10] [async-threads:1] [jit:ns] [systemtap]
Eshell V15.1 (press Ctrl+G to abort, type help(). for help)
1> A=ets:new(a,[]).
#Ref<0.1727942139.3704487938.40245>
2> B= <<0:100000000>>,ok.
ok
3> C=[binary:part(B, N, 100)||N<-lists:seq(1,500)],ok.
ok
4> ets:insert(A,{k,C}).
true
*** ERROR: Shell process terminated! ***

This makes the feature really hard to be used practically.

Is there a way to not double counting these referenced binary in heap? Thanks!

@zzydxm zzydxm added the bug Issue is reported as a bug label Sep 30, 2024
@IngelaAndin IngelaAndin added the team:VM Assigned to OTP team VM label Oct 1, 2024
@jhogberg
Copy link
Contributor

jhogberg commented Oct 1, 2024

ets:insert/2 and friends were correctly counted in 26, too: 27 just fixed under-counting on the creation of certain binaries. It may have made the symptoms worse but it's not the root cause.

Binaries will now only be double-counted when sharing is broken, such as when they're sent through a message (sharing-preserving helps here) or when inserted/looked up from ETS. I plan to fix this for good in OTP 29, along with the pesky issues of small references keeping large off-heap binaries alive. The changes in 27 were largely a preparation for this.

@jhogberg jhogberg self-assigned this Oct 1, 2024
@zzydxm
Copy link
Contributor Author

zzydxm commented Oct 1, 2024

Binaries will now only be double-counted when sharing is broken

Is this in 27.1 or some other versions?
C=[B||N<-lists:seq(1,10000)],ok. crashed seems advising the binary is actually double counted even if calculation is only local.
Also ets:lookup will crash too

Eshell V15.1 (press Ctrl+G to abort, type help(). for help)
1> A=ets:new(a,[]).
#Ref<0.2500968853.719978497.88894>
2> B= <<0:100000000>>,ok.
ok
3> C=[binary:part(B, N, 100)||N<-lists:seq(1,300)],ok.
ok
4> ets:insert(A,{k,C}).
true
5> ets:lookup(A,k),ok.
ok
6> ets:lookup(A,k),ok.
ok
*** ERROR: Shell process terminated! ***

@jhogberg
Copy link
Contributor

jhogberg commented Oct 1, 2024

That's not as local as you think, those statements don't run in the shell process but are sent between the shell and an evaluator process, breaking sharing. If you try it again with sharing-preserving enabled, it will take more effort to crash it. Likewise, ets:lookup/2 "double-counts" because sharing is removed: hence "and friends" in my previous post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM
Projects
None yet
Development

No branches or pull requests

3 participants