提交 0d4908ee 编写于 作者: D Daniel Gustafsson

Allocate histogram with palloc to avoid memleak

The histogram structure was allocated statically via malloc(), but it
had no data retention between calls as it was purely a microoptimization
to avoid the cost of repeated allocations. This lead to the allocated
memory leaking as it's not cleaned up automatically. Fix by pallocing
the memory instead and take the cost of repeat allocation.

Also ensure to properly clean up allocated memory on failure cases.
Reviewed-by: NHeikki Linnakangas <hlinnakangas@pivotal.io>
上级 d613a759
...@@ -168,11 +168,19 @@ gp_extract_feature_histogram_errout(char *msg) { ...@@ -168,11 +168,19 @@ gp_extract_feature_histogram_errout(char *msg) {
} }
SvecType *classify_document(char **features, int num_features, char **document, int num_words, int allocate) { SvecType *classify_document(char **features, int num_features, char **document, int num_words, int allocate) {
static float8 *histogram=NULL; float8 *histogram = NULL;
ENTRY item, *found_item; ENTRY item, *found_item;
int i; int i;
SvecType *output_sfv; //Output SFV in a sparse vector datatype SvecType *output_sfv; //Output SFV in a sparse vector datatype
/*
* We need to palloc the histogram array first, since the error cleanup
* process on memory pressure allocation failure won't be able to handle
* the malloc'ed ordinals array below. Should ordinals fail to allocate
* however, then the invoked ereport() will clean up histogram.
*/
histogram = (float8 *) palloc0(sizeof(float8) * num_features);
/* /*
* On saving the state between calls: * On saving the state between calls:
* *
...@@ -194,21 +202,22 @@ SvecType *classify_document(char **features, int num_features, char **document, ...@@ -194,21 +202,22 @@ SvecType *classify_document(char **features, int num_features, char **document,
#ifdef VERBOSE #ifdef VERBOSE
elog(NOTICE,"Classify_document allocating..., Number of features = %d\n",num_features); elog(NOTICE,"Classify_document allocating..., Number of features = %d\n",num_features);
#endif #endif
(void) hdestroy(); /*
ordinals = (int *)malloc(sizeof(int)*num_features); //Need to use malloc so that hdestroy() can be called. * Calling hdestroy() isn't guaranteed to free any memory allocated
* for the items, the details are implementation specific. Best case
* is that the item keys are free'd, while the item data pointers are
* never freed. The proper solution here is to move this to using a
* dynahash and properly manage the memory, but that remains a TODO
* for a rainy day still.
*/
hdestroy();
/* Need to use malloc so that hdestroy() can be called */
ordinals = (int *) malloc(sizeof(int) * num_features);
if (!ordinals) if (!ordinals)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"))); errmsg("out of memory")));
histogram = (float8 *)malloc(sizeof(float8)*num_features); //Use malloc because pallocs are cleaned up between queries
if (!histogram) {
free(ordinals);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
}
for (i=0; i<num_features; i++) { for (i=0; i<num_features; i++) {
ordinals[i] = i; ordinals[i] = i;
} }
...@@ -218,21 +227,39 @@ SvecType *classify_document(char **features, int num_features, char **document, ...@@ -218,21 +227,39 @@ SvecType *classify_document(char **features, int num_features, char **document,
if (features[i] != NULL) { if (features[i] != NULL) {
item.key = strdup(features[i]); item.key = strdup(features[i]);
if (!item.key) if (!item.key)
{
hdestroy();
free(ordinals);
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY), (errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"))); errmsg("out of memory")));
item.data = (void *)(&(ordinals[i]));
(void) hsearch(item,ENTER);
}
}
} }
/* If the hash table has the entry already */
if (hsearch(item, FIND) != NULL)
free(item.key);
else
{
item.data = (void *)(&(ordinals[i]));
/* /*
* For all items in the document, probe hash table to find matches. When we * If the ENTER action returns NULL it means that we are
* find one, increment the counter at the appropriate ordinal. * out of memory and need to error out of this, cleaning
* up as best as we can.
*/ */
for (i=0;i<num_features;i++) //Zero out the found count array for this document if (hsearch(item,ENTER) == NULL)
histogram[i]=0; {
hdestroy();
free(item.key);
free(ordinals);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
}
}
}
}
}
for (i=0;i<num_words;i++) { for (i=0;i<num_words;i++) {
if (document[i] != NULL) if (document[i] != NULL)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册