From a51fea68bbcf341bf7857a6bd3f0c17ffd0402bb Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Tue, 15 Feb 2011 16:51:38 +0100 Subject: Do not save parameter list for any temporary processes Previous commit changed the supervisor to not save parameter lists for temporary processes supervised by simple-one-for-one supervisors. But it is unnecessary to save them for any temporary processes as they should not be restarted. Proably the biggest gain is in the simple-one-for-one case. Also changed the test case count_children_memory so it does not test that which_children will produce garbage that must be reclaimed later. This is a strange thing to test and it is no longer true for all invocations of which_children. --- lib/stdlib/test/supervisor_SUITE.erl | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'lib/stdlib/test/supervisor_SUITE.erl') diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl index 039ea298c4..4708658a6d 100644 --- a/lib/stdlib/test/supervisor_SUITE.erl +++ b/lib/stdlib/test/supervisor_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1279,7 +1279,7 @@ count_children_allocator_test(MemoryState) -> lists:all(fun(State) -> State == {e, true} end, AllocStates). count_children_memory(doc) -> - ["Test that which_children eats memory, but count_children does not."]; + ["Test that count_children does not eat memory."]; count_children_memory(suite) -> MemoryState = erlang:system_info(allocator), case count_children_allocator_test(MemoryState) of @@ -1323,8 +1323,8 @@ count_children_memory(Config) when is_list(Config) -> ?line ChildCount3 = ChildCount2, %% count_children consumes memory using an accumulator function, - %% but the space can be reclaimed incrementally, whereas - %% which_children generates a return list. + %% but the space can be reclaimed incrementally, + %% which_children may generate garbage that will reclaimed later. case (Size5 =< Size4) of true -> ok; false -> @@ -1336,19 +1336,7 @@ count_children_memory(Config) when is_list(Config) -> ?line test_server:fail({count_children, used_more_memory}) end, - case Size4 > Size3 of - true -> ok; - false -> - ?line test_server:fail({which_children, used_no_memory}) - end, - case Size6 > Size5 of - true -> ok; - false -> - ?line test_server:fail({which_children, used_no_memory}) - end, - [exit(Pid, kill) || {undefined, Pid, worker, _Modules} <- Children3], test_server:sleep(100), ?line [1,0,0,0] = get_child_counts(sup_test), - ok. -- cgit v1.2.3 From a317dc1cce5705a5ccace98fdef59704e7240b6d Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Tue, 22 Feb 2011 11:24:53 +0100 Subject: Added test case do_not_save_start_parameters_for_temporary_children and fixed dialyzer spec. --- lib/stdlib/test/supervisor_SUITE.erl | 86 +++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) (limited to 'lib/stdlib/test/supervisor_SUITE.erl') diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl index 4708658a6d..4ee323ee62 100644 --- a/lib/stdlib/test/supervisor_SUITE.erl +++ b/lib/stdlib/test/supervisor_SUITE.erl @@ -50,7 +50,8 @@ simple_one_for_one_extra/1]). %% Misc tests --export([child_unlink/1, tree/1, count_children_memory/1]). +-export([child_unlink/1, tree/1, count_children_memory/1, + do_not_save_start_parameters_for_temporary_children/1]). %------------------------------------------------------------------------- @@ -61,7 +62,7 @@ all(suite) -> restart_one_for_one, restart_one_for_all, restart_simple_one_for_one, restart_rest_for_one, normal_termination, abnormal_termination, child_unlink, tree, - count_children_memory]}. + count_children_memory, do_not_save_start_parameters_for_temporary_children]}. start(InitResult) -> @@ -1340,3 +1341,84 @@ count_children_memory(Config) when is_list(Config) -> test_server:sleep(100), ?line [1,0,0,0] = get_child_counts(sup_test), ok. +%------------------------------------------------------------------------- +do_not_save_start_parameters_for_temporary_children(doc) -> + ["Temporary children shall not be restarted so they should not" + "save start parameters, as it potentially can" + "take up a huge amount of memory for no purpose."]; +do_not_save_start_parameters_for_temporary_children(suite) -> + []; +do_not_save_start_parameters_for_temporary_children(Config) when is_list(Config) -> + process_flag(trap_exit, true), + dont_save_start_parameters_for_temporary_children(one_for_all), + dont_save_start_parameters_for_temporary_children(one_for_one), + dont_save_start_parameters_for_temporary_children(rest_for_one), + dont_save_start_parameters_for_temporary_children(simple_one_for_one). + +dont_save_start_parameters_for_temporary_children(simple_one_for_one = Type) -> + Permanent = {child, {supervisor_1, start_child, []}, + permanent, 1000, worker, []}, + Transient = {child, {supervisor_1, start_child, []}, + transient, 1000, worker, []}, + Temporary = {child, {supervisor_1, start_child, []}, + temporary, 1000, worker, []}, + {ok, Sup1} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, [Permanent]}}), + {ok, Sup2} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, [Transient]}}), + {ok, Sup3} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, [Temporary]}}), + + LargeList = lists:duplicate(10, "Potentially large"), + + start_children(Sup1, [LargeList], 100), + start_children(Sup2, [LargeList], 100), + start_children(Sup3, [LargeList], 100), + + [{memory,Mem1}] = process_info(Sup1, [memory]), + [{memory,Mem2}] = process_info(Sup2, [memory]), + [{memory,Mem3}] = process_info(Sup3, [memory]), + + true = (Mem3 < Mem1) and (Mem3 < Mem2), + + exit(Sup1, shutdown), + exit(Sup2, shutdown), + exit(Sup3, shutdown); + +dont_save_start_parameters_for_temporary_children(Type) -> + {ok, Sup1} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, []}}), + {ok, Sup2} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, []}}), + {ok, Sup3} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, []}}), + + LargeList = lists:duplicate(10, "Potentially large"), + + Permanent = {child1, {supervisor_1, start_child, [LargeList]}, + permanent, 1000, worker, []}, + Transient = {child2, {supervisor_1, start_child, [LargeList]}, + transient, 1000, worker, []}, + Temporary = {child3, {supervisor_1, start_child, [LargeList]}, + temporary, 1000, worker, []}, + + start_children(Sup1, Permanent, 100), + start_children(Sup2, Transient, 100), + start_children(Sup3, Temporary, 100), + + [{memory,Mem1}] = process_info(Sup1, [memory]), + [{memory,Mem2}] = process_info(Sup2, [memory]), + [{memory,Mem3}] = process_info(Sup3, [memory]), + + true = (Mem3 < Mem1) and (Mem3 < Mem2), + + exit(Sup1, shutdown), + exit(Sup2, shutdown), + exit(Sup3, shutdown). + +start_children(_,_, 0) -> + ok; +start_children(Sup, Args, N) -> + Spec = child_spec(Args, N), + {ok, _, _} = supervisor:start_child(Sup, Spec), + start_children(Sup, Args, N-1). + +child_spec([_|_] = SimpleOneForOneArgs, _) -> + SimpleOneForOneArgs; +child_spec({Name, MFA, RestartType, Shutdown, Type, Modules}, N) -> + NewName = list_to_atom((atom_to_list(Name) ++ integer_to_list(N))), + {NewName, MFA, RestartType, Shutdown, Type, Modules}. -- cgit v1.2.3