Tue, 13 Mar 2012 21:12:53 +0100
7152954: G1: Native memory leak during full GCs
Summary: Add destructor to TruncatedSeq and call delete when necessary
Reviewed-by: johnc, tonyp
1.1 --- a/src/share/vm/gc_implementation/g1/survRateGroup.cpp Mon Mar 12 13:12:07 2012 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/survRateGroup.cpp Tue Mar 13 21:12:53 2012 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -38,33 +38,36 @@ 1.11 _summary_surv_rates(NULL), 1.12 _surv_rate(NULL), 1.13 _accum_surv_rate_pred(NULL), 1.14 - _surv_rate_pred(NULL) 1.15 -{ 1.16 + _surv_rate_pred(NULL), 1.17 + _stats_arrays_length(0) { 1.18 reset(); 1.19 if (summary_surv_rates_len > 0) { 1.20 size_t length = summary_surv_rates_len; 1.21 - _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length); 1.22 - if (_summary_surv_rates == NULL) { 1.23 - vm_exit_out_of_memory(sizeof(NumberSeq*) * length, 1.24 - "Not enough space for surv rate summary"); 1.25 + _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length); 1.26 + for (size_t i = 0; i < length; ++i) { 1.27 + _summary_surv_rates[i] = new NumberSeq(); 1.28 } 1.29 - for (size_t i = 0; i < length; ++i) 1.30 - _summary_surv_rates[i] = new NumberSeq(); 1.31 } 1.32 1.33 start_adding_regions(); 1.34 } 1.35 1.36 - 1.37 -void SurvRateGroup::reset() 1.38 -{ 1.39 +void SurvRateGroup::reset() { 1.40 _all_regions_allocated = 0; 1.41 _setup_seq_num = 0; 1.42 - _stats_arrays_length = 0; 1.43 _accum_surv_rate = 0.0; 1.44 _last_pred = 0.0; 1.45 // the following will set up the arrays with length 1 1.46 _region_num = 1; 1.47 + 1.48 + // The call to stop_adding_regions() will use "new" to refill 1.49 + // the _surv_rate_pred array, so we need to make sure to call 1.50 + // "delete". 1.51 + for (size_t i = 0; i < _stats_arrays_length; ++i) { 1.52 + delete _surv_rate_pred[i]; 1.53 + } 1.54 + _stats_arrays_length = 0; 1.55 + 1.56 stop_adding_regions(); 1.57 guarantee( _stats_arrays_length == 1, "invariant" ); 1.58 guarantee( _surv_rate_pred[0] != NULL, "invariant" ); 1.59 @@ -73,72 +76,47 @@ 1.60 _region_num = 0; 1.61 } 1.62 1.63 - 1.64 void 1.65 SurvRateGroup::start_adding_regions() { 1.66 _setup_seq_num = _stats_arrays_length; 1.67 _region_num = 0; 1.68 _accum_surv_rate = 0.0; 1.69 - 1.70 -#if 0 1.71 - gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d", 1.72 - _name, _setup_seq_num, _region_num); 1.73 -#endif // 0 1.74 } 1.75 1.76 void 1.77 SurvRateGroup::stop_adding_regions() { 1.78 - 1.79 -#if 0 1.80 - gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num); 1.81 -#endif // 0 1.82 - 1.83 if (_region_num > _stats_arrays_length) { 1.84 double* old_surv_rate = _surv_rate; 1.85 double* old_accum_surv_rate_pred = _accum_surv_rate_pred; 1.86 TruncatedSeq** old_surv_rate_pred = _surv_rate_pred; 1.87 1.88 _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num); 1.89 - if (_surv_rate == NULL) { 1.90 - vm_exit_out_of_memory(sizeof(double) * _region_num, 1.91 - "Not enough space for surv rate array."); 1.92 + _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num); 1.93 + _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num); 1.94 + 1.95 + for (size_t i = 0; i < _stats_arrays_length; ++i) { 1.96 + _surv_rate_pred[i] = old_surv_rate_pred[i]; 1.97 } 1.98 - _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num); 1.99 - if (_accum_surv_rate_pred == NULL) { 1.100 - vm_exit_out_of_memory(sizeof(double) * _region_num, 1.101 - "Not enough space for accum surv rate pred array."); 1.102 - } 1.103 - _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num); 1.104 - if (_surv_rate == NULL) { 1.105 - vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num, 1.106 - "Not enough space for surv rate pred array."); 1.107 - } 1.108 - 1.109 - for (size_t i = 0; i < _stats_arrays_length; ++i) 1.110 - _surv_rate_pred[i] = old_surv_rate_pred[i]; 1.111 - 1.112 -#if 0 1.113 - gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d", 1.114 - _name, _array_length, _region_num - 1); 1.115 -#endif // 0 1.116 - 1.117 for (size_t i = _stats_arrays_length; i < _region_num; ++i) { 1.118 _surv_rate_pred[i] = new TruncatedSeq(10); 1.119 - // _surv_rate_pred[i]->add(last_pred); 1.120 } 1.121 1.122 _stats_arrays_length = _region_num; 1.123 1.124 - if (old_surv_rate != NULL) 1.125 + if (old_surv_rate != NULL) { 1.126 FREE_C_HEAP_ARRAY(double, old_surv_rate); 1.127 - if (old_accum_surv_rate_pred != NULL) 1.128 + } 1.129 + if (old_accum_surv_rate_pred != NULL) { 1.130 FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred); 1.131 - if (old_surv_rate_pred != NULL) 1.132 - FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred); 1.133 + } 1.134 + if (old_surv_rate_pred != NULL) { 1.135 + FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred); 1.136 + } 1.137 } 1.138 1.139 - for (size_t i = 0; i < _stats_arrays_length; ++i) 1.140 + for (size_t i = 0; i < _stats_arrays_length; ++i) { 1.141 _surv_rate[i] = 0.0; 1.142 + } 1.143 } 1.144 1.145 double 1.146 @@ -187,12 +165,6 @@ 1.147 SurvRateGroup::all_surviving_words_recorded(bool propagate) { 1.148 if (propagate && _region_num > 0) { // conservative 1.149 double surv_rate = _surv_rate_pred[_region_num-1]->last(); 1.150 - 1.151 -#if 0 1.152 - gclog_or_tty->print_cr("propagating %1.2lf from %d to %d", 1.153 - surv_rate, _curr_length, _array_length - 1); 1.154 -#endif // 0 1.155 - 1.156 for (size_t i = _region_num; i < _stats_arrays_length; ++i) { 1.157 guarantee( _surv_rate[i] <= 0.00001, 1.158 "the slot should not have been updated" );
2.1 --- a/src/share/vm/utilities/numberSeq.cpp Mon Mar 12 13:12:07 2012 -0700 2.2 +++ b/src/share/vm/utilities/numberSeq.cpp Tue Mar 13 21:12:53 2012 +0100 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -156,6 +156,10 @@ 2.11 _sequence[i] = 0.0; 2.12 } 2.13 2.14 +TruncatedSeq::~TruncatedSeq() { 2.15 + FREE_C_HEAP_ARRAY(double, _sequence); 2.16 +} 2.17 + 2.18 void TruncatedSeq::add(double val) { 2.19 AbsSeq::add(val); 2.20
3.1 --- a/src/share/vm/utilities/numberSeq.hpp Mon Mar 12 13:12:07 2012 -0700 3.2 +++ b/src/share/vm/utilities/numberSeq.hpp Tue Mar 13 21:12:53 2012 +0100 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -118,6 +118,7 @@ 3.11 // accepts a value for L 3.12 TruncatedSeq(int length = DefaultSeqLength, 3.13 double alpha = DEFAULT_ALPHA_VALUE); 3.14 + ~TruncatedSeq(); 3.15 virtual void add(double val); 3.16 virtual double maximum() const; 3.17 virtual double last() const; // the last value added to the sequence