Commit 7a82ba4f authored by Guolin Ke's avatar Guolin Ke
Browse files

[python] fix python memory leak (#840)

* try to fix python memory leak

* fix parameter error.

* free old handle in _load_model_from_string .

* fix best_score & best_iteration

* refine logics.

* fix tests.
parent 943edca7
...@@ -1227,7 +1227,7 @@ class Booster(object): ...@@ -1227,7 +1227,7 @@ class Booster(object):
silent : boolean, optional silent : boolean, optional
Whether print messages during construction Whether print messages during construction
""" """
self.handle = ctypes.c_void_p() self.handle = None
self.__need_reload_eval_info = True self.__need_reload_eval_info = True
self.__train_data_name = "training" self.__train_data_name = "training"
self.__attr = {} self.__attr = {}
...@@ -1246,6 +1246,7 @@ class Booster(object): ...@@ -1246,6 +1246,7 @@ class Booster(object):
raise TypeError('Training data should be Dataset instance, met {}'.format(type(train_set).__name__)) raise TypeError('Training data should be Dataset instance, met {}'.format(type(train_set).__name__))
params_str = param_dict_to_str(params) params_str = param_dict_to_str(params)
"""construct booster object""" """construct booster object"""
self.handle = ctypes.c_void_p()
_safe_call(_LIB.LGBM_BoosterCreate( _safe_call(_LIB.LGBM_BoosterCreate(
train_set.construct().handle, train_set.construct().handle,
c_str(params_str), c_str(params_str),
...@@ -1273,6 +1274,7 @@ class Booster(object): ...@@ -1273,6 +1274,7 @@ class Booster(object):
elif model_file is not None: elif model_file is not None:
"""Prediction task""" """Prediction task"""
out_num_iterations = ctypes.c_int(0) out_num_iterations = ctypes.c_int(0)
self.handle = ctypes.c_void_p()
_safe_call(_LIB.LGBM_BoosterCreateFromModelfile( _safe_call(_LIB.LGBM_BoosterCreateFromModelfile(
c_str(model_file), c_str(model_file),
ctypes.byref(out_num_iterations), ctypes.byref(out_num_iterations),
...@@ -1327,6 +1329,10 @@ class Booster(object): ...@@ -1327,6 +1329,10 @@ class Booster(object):
self.__dict__.pop('valid_sets', None) self.__dict__.pop('valid_sets', None)
self.__num_dataset = 0 self.__num_dataset = 0
def _free_buffer(self):
self.__inner_predict_buffer = []
self.__is_predicted_cur_iter = []
def set_train_data_name(self, name): def set_train_data_name(self, name):
self.__train_data_name = name self.__train_data_name = name
...@@ -1547,6 +1553,10 @@ class Booster(object): ...@@ -1547,6 +1553,10 @@ class Booster(object):
def _load_model_from_string(self, model_str): def _load_model_from_string(self, model_str):
"""[Private] Load model from string""" """[Private] Load model from string"""
if self.handle is not None:
_safe_call(_LIB.LGBM_BoosterFree(self.handle))
self._free_buffer()
self.handle = ctypes.c_void_p()
out_num_iterations = ctypes.c_int(0) out_num_iterations = ctypes.c_int(0)
_safe_call(_LIB.LGBM_BoosterLoadModelFromString( _safe_call(_LIB.LGBM_BoosterLoadModelFromString(
c_str(model_str), c_str(model_str),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment