diff options
author | Lukas Larsson <[email protected]> | 2019-03-25 14:34:45 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2019-03-25 16:34:11 +0100 |
commit | 7b6c36d65fabd9ba43beb2fa56cc1a17249aac64 (patch) | |
tree | bc7a39d4f5d7886cb67bfc1df5a3a69a896dfb8b | |
parent | 6907100826bf1956a8dbeb16ba2e736199913d0a (diff) | |
download | otp-7b6c36d65fabd9ba43beb2fa56cc1a17249aac64.tar.gz otp-7b6c36d65fabd9ba43beb2fa56cc1a17249aac64.tar.bz2 otp-7b6c36d65fabd9ba43beb2fa56cc1a17249aac64.zip |
erts: Include external msg in need of GC
When many external messages suddenly appear in the mailbox
the young gen size is adjusted accordingly but it was
immediately shrunk as the data was not counted towards the
shrink size. This commit includes the ext dist size in the
shrink calculation which means that the decode of the external
messages will not trigger as many GCs which means much better
performance.
-rw-r--r-- | erts/emulator/beam/erl_gc.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index 9317850d96..67a73e4d57 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -577,7 +577,7 @@ force_reschedule: } static ERTS_FORCE_INLINE Uint -young_gen_usage(Process *p) +young_gen_usage(Process *p, Uint *ext_msg_usage) { Uint hsz; Eterm *aheap; @@ -604,7 +604,10 @@ young_gen_usage(Process *p) if (ERTS_SIG_IS_MSG(mp) && mp->data.attached && mp->data.attached != ERTS_MSG_COMBINED_HFRAG) { - hsz += erts_msg_attached_data_size(mp); + Uint sz = erts_msg_attached_data_size(mp); + if (ERTS_SIG_IS_EXTERNAL_MSG(mp)) + *ext_msg_usage += sz; + hsz += sz; } }); } @@ -676,6 +679,7 @@ garbage_collect(Process* p, ErlHeapFragment *live_hf_end, { Uint reclaimed_now = 0; Uint ygen_usage; + Uint ext_msg_usage = 0; Eterm gc_trace_end_tag; int reds; ErtsMonotonicTime start_time; @@ -698,7 +702,7 @@ garbage_collect(Process* p, ErlHeapFragment *live_hf_end, return delay_garbage_collection(p, live_hf_end, need, fcalls); } - ygen_usage = max_young_gen_usage ? max_young_gen_usage : young_gen_usage(p); + ygen_usage = max_young_gen_usage ? max_young_gen_usage : young_gen_usage(p, &ext_msg_usage); if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) { check_for_possibly_long_gc(p, ygen_usage); @@ -739,7 +743,7 @@ garbage_collect(Process* p, ErlHeapFragment *live_hf_end, trace_gc(p, am_gc_minor_start, need, THE_NON_VALUE); } DTRACE2(gc_minor_start, pidbuf, need); - reds = minor_collection(p, live_hf_end, need, objv, nobj, + reds = minor_collection(p, live_hf_end, need + ext_msg_usage, objv, nobj, ygen_usage, &reclaimed_now); DTRACE2(gc_minor_end, pidbuf, reclaimed_now); if (reds == -1) { @@ -764,7 +768,7 @@ do_major_collection: trace_gc(p, am_gc_major_start, need, THE_NON_VALUE); } DTRACE2(gc_major_start, pidbuf, need); - reds = major_collection(p, live_hf_end, need, objv, nobj, + reds = major_collection(p, live_hf_end, need + ext_msg_usage, objv, nobj, ygen_usage, &reclaimed_now); if (ERTS_SCHEDULER_IS_DIRTY(esdp)) p->flags &= ~(F_DIRTY_MAJOR_GC|F_DIRTY_MINOR_GC); @@ -1101,6 +1105,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, Eterm* old_htop; Uint n; Uint ygen_usage = 0; + Uint ext_msg_usage = 0; struct erl_off_heap_header** prev = NULL; Sint64 reds; int hibernated = !!(p->flags & F_HIBERNATED); @@ -1118,7 +1123,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, p->flags &= ~F_DIRTY_CLA; else { Uint size = byte_lit_size/sizeof(Uint); - ygen_usage = young_gen_usage(p); + ygen_usage = young_gen_usage(p, &ext_msg_usage); if (hibernated) size = size*2 + 3*ygen_usage; else @@ -1130,7 +1135,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, } } - reds = (Sint64) garbage_collect(p, ERTS_INVALID_HFRAG_PTR, 0, + reds = (Sint64) garbage_collect(p, ERTS_INVALID_HFRAG_PTR, ext_msg_usage, p->arg_reg, p->arity, fcalls, ygen_usage); if (ERTS_PROC_IS_EXITING(p)) { @@ -1348,6 +1353,9 @@ minor_collection(Process* p, ErlHeapFragment *live_hf_end, Eterm *mature = p->abandoned_heap ? p->abandoned_heap : p->heap; Uint mature_size = p->high_water - mature; Uint size_before = ygen_usage; +#ifdef DEBUG + Uint debug_tmp = 0; +#endif /* * Check if we have gone past the max heap size limit @@ -1484,7 +1492,7 @@ minor_collection(Process* p, ErlHeapFragment *live_hf_end, process from there */ ASSERT(!MAX_HEAP_SIZE_GET(p) || !(MAX_HEAP_SIZE_FLAGS_GET(p) & MAX_HEAP_SIZE_KILL) || - MAX_HEAP_SIZE_GET(p) > (young_gen_usage(p) + + MAX_HEAP_SIZE_GET(p) > (young_gen_usage(p, &debug_tmp) + (OLD_HEND(p) - OLD_HEAP(p)) + (HEAP_END(p) - HEAP_TOP(p)))); |