mirror of https://github.com/milvus-io/milvus.git
Return malloc_trim result and log if malloc_trim successfully (#17959)
Signed-off-by: bigsheeper <yihao.dai@zilliz.com>pull/17987/head
parent
2b557355db
commit
641fb96958
|
@ -24,11 +24,16 @@
|
|||
#include "exceptions/EasyAssert.h"
|
||||
#include "log/Log.h"
|
||||
|
||||
void
|
||||
int
|
||||
DoMallocTrim() {
|
||||
#ifdef __linux__
|
||||
malloc_trim(0);
|
||||
/*
|
||||
* The malloc_trim() function returns 1 if memory was actually released back to the system,
|
||||
* or 0 if it was not possible to release any memory.
|
||||
*/
|
||||
return malloc_trim(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
@ -75,16 +80,19 @@ ParseMallocInfo() {
|
|||
}
|
||||
|
||||
CStatus
|
||||
PurgeMemory(uint64_t max_bins_size) {
|
||||
PurgeMemory(uint64_t max_bins_size, int32_t* res) {
|
||||
try {
|
||||
auto fast_and_rest_total = ParseMallocInfo();
|
||||
if (fast_and_rest_total >= max_bins_size) {
|
||||
LOG_SEGCORE_DEBUG_ << "Purge memory fragmentation, max_bins_size(bytes) = " << max_bins_size
|
||||
<< ", fast_and_rest_total(bytes) = " << fast_and_rest_total;
|
||||
DoMallocTrim();
|
||||
*res = DoMallocTrim();
|
||||
} else {
|
||||
*res = 0;
|
||||
}
|
||||
return milvus::SuccessCStatus();
|
||||
} catch (std::exception& e) {
|
||||
*res = 0;
|
||||
return milvus::FailureCStatus(UnexpectedError, e.what());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
* ref: <https://sourceware.org/glibc/wiki/MallocInternals>
|
||||
*/
|
||||
CStatus
|
||||
PurgeMemory(uint64_t max_bins_size);
|
||||
PurgeMemory(uint64_t max_bins_size, int32_t* res);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -198,8 +198,10 @@ serialize(const Message* msg) {
|
|||
// auto run_times = 1000000;
|
||||
// auto start = std::chrono::high_resolution_clock::now();
|
||||
//
|
||||
// int32_t res;
|
||||
// for (int i = 0; i < run_times; i++) {
|
||||
// PurgeMemory(UINT64_MAX /*never malloc_trim*/);
|
||||
// PurgeMemory(UINT64_MAX /*never malloc_trim*/, &res);
|
||||
// assert(res == 0);
|
||||
// }
|
||||
//
|
||||
// auto stop = std::chrono::high_resolution_clock::now();
|
||||
|
@ -210,10 +212,13 @@ serialize(const Message* msg) {
|
|||
//}
|
||||
|
||||
TEST(Common, Memory) {
|
||||
auto res = PurgeMemory(UINT64_MAX /*never malloc_trim*/);
|
||||
assert(res.error_code == Success);
|
||||
res = PurgeMemory(0);
|
||||
assert(res.error_code == Success);
|
||||
int32_t res;
|
||||
auto status = PurgeMemory(UINT64_MAX /*never malloc_trim*/, &res);
|
||||
assert(res == 0);
|
||||
assert(status.error_code == Success);
|
||||
status = PurgeMemory(0 /*do malloc_trim*/, &res);
|
||||
assert(res == 1);
|
||||
assert(status.error_code == Success);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@ package querynode
|
|||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
memutil "github.com/milvus-io/milvus/internal/util/memutil"
|
||||
|
@ -139,13 +140,20 @@ func deleteSearchResultDataBlobs(cSearchResultDataBlobs searchResultDataBlobs) {
|
|||
// try to do a purgeMemory operation after DeleteSearchResultDataBlobs
|
||||
usedMem := metricsinfo.GetUsedMemoryCount()
|
||||
if usedMem == 0 {
|
||||
log.Error("Get 0 uesdMemory when deleteSearchResultDataBlobs, which is unexpected")
|
||||
log.Error("Get 0 usedMemory when deleteSearchResultDataBlobs, which is unexpected")
|
||||
return
|
||||
}
|
||||
maxBinsSize := uint64(float64(usedMem) * Params.CommonCfg.MemPurgeRatio)
|
||||
if err := memutil.PurgeMemory(maxBinsSize); err != nil {
|
||||
released, err := memutil.PurgeMemory(maxBinsSize)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
if released {
|
||||
log.Info("purge memory done, memory was released back to the system successfully",
|
||||
zap.Uint64("usedMem", usedMem),
|
||||
zap.Float64("memPurgeRatio", Params.CommonCfg.MemPurgeRatio),
|
||||
zap.Uint64("maxBinsSize", maxBinsSize))
|
||||
}
|
||||
}
|
||||
|
||||
func deleteSearchResults(results []*SearchResult) {
|
||||
|
|
|
@ -104,6 +104,15 @@ func TestReduce_AllFunc(t *testing.T) {
|
|||
deleteCollection(collection)
|
||||
}
|
||||
|
||||
func TestReduce_deleteSearchResultDataBlobs(t *testing.T) {
|
||||
t.Run("test purge memory", func(t *testing.T) {
|
||||
bak := Params.CommonCfg.MemPurgeRatio
|
||||
Params.CommonCfg.MemPurgeRatio = 0
|
||||
deleteSearchResultDataBlobs(nil)
|
||||
Params.CommonCfg.MemPurgeRatio = bak
|
||||
})
|
||||
}
|
||||
|
||||
func TestReduce_Invalid(t *testing.T) {
|
||||
t.Run("nil plan", func(t *testing.T) {
|
||||
plan := &SearchPlan{}
|
||||
|
|
|
@ -24,16 +24,17 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
func PurgeMemory(maxBinsSize uint64) error {
|
||||
func PurgeMemory(maxBinsSize uint64) (bool, error) {
|
||||
var res C.int32_t
|
||||
cMaxBinsSize := C.uint64_t(maxBinsSize)
|
||||
status := C.PurgeMemory(cMaxBinsSize)
|
||||
status := C.PurgeMemory(cMaxBinsSize, &res)
|
||||
if status.error_code == 0 {
|
||||
return nil
|
||||
return int32(res) > 0, nil
|
||||
}
|
||||
defer C.free(unsafe.Pointer(status.error_msg))
|
||||
|
||||
errorMsg := string(C.GoString(status.error_msg))
|
||||
errorCode := int32(status.error_code)
|
||||
|
||||
return fmt.Errorf("PurgeMemory failed, errorCode = %d, errorMsg = %s", errorCode, errorMsg)
|
||||
return false, fmt.Errorf("PurgeMemory failed, errorCode = %d, errorMsg = %s", errorCode, errorMsg)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
package metricsinfo
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -23,6 +24,16 @@ func TestPurgeMemory(t *testing.T) {
|
|||
usedMem := metricsinfo.GetUsedMemoryCount()
|
||||
assert.True(t, usedMem > 0)
|
||||
maxBinsSize := uint64(float64(usedMem) * 0.2)
|
||||
err := PurgeMemory(maxBinsSize)
|
||||
_, err := PurgeMemory(maxBinsSize)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// do not malloc_trim
|
||||
res, err := PurgeMemory(math.MaxUint64)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, res)
|
||||
|
||||
// do malloc_trim
|
||||
res, err = PurgeMemory(0)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, res)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue