@@ -24,50 +24,41 @@ module JavaBuildpack::Jre
2424 # A utility for defaulting Java memory settings.
2525 class WeightBalancingMemoryHeuristic
2626
27- # @!attribute [r] output
28- # @return [Hash] a hash of memory types and corresponding memory sizes, e.g. {'memory-type' => '1M'}
29- attr_reader :output
30-
31- # Creates an instance based on user-specified sizes weightings, and the application's memory size in $MEMORY_LIMIT.
27+ # Creates an instance based on a hash containing memory settings, and the application's memory size in
28+ # $MEMORY_LIMIT.
3229 #
33- # @param [Hash<String, Numeric>] specified_sizes any sizings specified by the user
34- # @param [Hash<String, Numeric>] weightings the weightings for this version of the JRE
35- def initialize ( specified_sizes , weightings )
36- memory_limit = MemoryLimit . memory_limit
37-
38- buckets = WeightBalancingMemoryHeuristic . create_memory_buckets ( specified_sizes , weightings , memory_limit )
30+ # @param [Hash<String, Numeric>] sizes any sizings specified by the user
31+ # @param [Hash<String, Numeric>] heuristics the memory heuristics specified by the user
32+ # @param [Array<String>] valid_sizes the valid size keys
33+ # @param [Array<String>] valid_heuristics the valid heuristics keys
34+ # @param [Hash<String, String>] java_opts a mapping from a memory type to a +JAVA_OPTS+ option
35+ def initialize ( sizes , heuristics , valid_sizes , valid_heuristics , java_opts )
36+ validate 'size' , valid_sizes , sizes . keys
37+ validate 'heuristic' , valid_heuristics , heuristics . keys
38+
39+ @sizes = sizes
40+ @heuristics = heuristics
41+ @java_opts = java_opts
42+ end
3943
40- WeightBalancingMemoryHeuristic . balance_buckets ( specified_sizes , buckets , memory_limit )
44+ def resolve
45+ memory_limit = MemoryLimit . memory_limit
46+ buckets = create_memory_buckets ( @sizes , @heuristics , memory_limit )
4147
42- WeightBalancingMemoryHeuristic . issue_memory_wastage_warning ( buckets ) if memory_limit
48+ balance_buckets ( @sizes , buckets , memory_limit )
49+ issue_memory_wastage_warning ( buckets ) if memory_limit
4350
44- @output = { }
45- buckets . each_pair do |memory_type , bucket |
46- @output [ memory_type ] = bucket . size . to_s if bucket . size
47- end
51+ buckets . map { |type , bucket | "#{ @java_opts [ type ] } #{ bucket . size } " if bucket . size && @java_opts . has_key? ( type ) } . compact
4852 end
4953
5054 private
5155
52- def self . create_memory_buckets ( specified_sizes , weightings , memory_limit )
53- buckets = { }
54- total_weighting = 0
55- weightings . each_pair do |memory_type , weighting |
56- value = specified_sizes [ memory_type ]
57-
58- buckets [ memory_type ] = WeightBalancingMemoryHeuristic . create_memory_bucket (
59- memory_type , weighting , value ? MemorySize . new ( value ) : nil , memory_limit )
60-
61- total_weighting += weighting
62- end
63-
64- raise "Invalid configuration: sum of weightings is greater than 1" if total_weighting > 1
65- buckets
66- end
56+ NATIVE_MEMORY_WARNING_FACTOR = 3
6757
68- def self . balance_buckets ( specified_sizes , buckets , memory_limit )
58+ def balance_buckets ( sizes , buckets , memory_limit )
6959 total_excess = MemorySize . ZERO
7060 total_adjustable_weighting = 0
61+
7162 buckets . each_value do |bucket |
7263 xs = bucket . excess
7364 total_excess = total_excess + xs
@@ -76,26 +67,50 @@ def self.balance_buckets(specified_sizes, buckets, memory_limit)
7667
7768 buckets . each_value do |bucket |
7869 bucket . adjust ( total_excess , total_adjustable_weighting )
79- raise "Total memory #{ memory_limit } exceeded by configured memory #{ specified_sizes } " if bucket . size && bucket . size < MemorySize . ZERO
70+ raise "Total memory #{ memory_limit } exceeded by configured memory #{ sizes } " if bucket . size && bucket . size < MemorySize . ZERO
8071 end
8172 end
8273
83- NATIVE_MEMORY_WARNING_FACTOR = 3
84-
85- def self . create_memory_bucket ( memory_type , weighting , size , total_memory )
86- if memory_type == 'stack'
87- StackMemoryBucket . new ( weighting , size , total_memory )
74+ def create_memory_bucket ( type , weighting , size , memory_limit )
75+ if type == 'stack'
76+ StackMemoryBucket . new ( weighting , size , memory_limit )
8877 else
89- MemoryBucket . new ( memory_type , weighting , size , true , total_memory )
78+ MemoryBucket . new ( type , weighting , size , true , memory_limit )
9079 end
9180 end
9281
93- def self . issue_memory_wastage_warning ( buckets )
82+ def create_memory_buckets ( sizes , heuristics , memory_limit )
83+ buckets = { }
84+ total_weighting = 0
85+
86+ heuristics . each_pair do |type , weighting |
87+ size = nil_safe_size sizes [ type ]
88+ buckets [ type ] = create_memory_bucket ( type , weighting , size , memory_limit )
89+ total_weighting += weighting
90+ end
91+
92+ raise "Invalid configuration: sum of weightings is greater than 1" if total_weighting > 1
93+
94+ buckets
95+ end
96+
97+ def issue_memory_wastage_warning ( buckets )
9498 native_bucket = buckets [ 'native' ]
9599 if native_bucket && native_bucket . size > native_bucket . default_size * NATIVE_MEMORY_WARNING_FACTOR
96100 $stderr. puts "-----> WARNING: there is #{ NATIVE_MEMORY_WARNING_FACTOR } times more spare native memory than the default, so configured Java memory may be too small."
97101 end
98102 end
99103
104+ def nil_safe_size ( size )
105+ size ? MemorySize . new ( size ) : nil
106+ end
107+
108+ def validate ( type , expected , actual )
109+ actual . each do |key |
110+ raise "'#{ key } ' is not a valid memory #{ type } " unless expected . include? key
111+ end
112+ end
113+
100114 end
115+
101116end
0 commit comments