Skip to content

runtime/cgo: Memory RSS has been growing abnormally when call cgo and go #43160

Closed
@bluce-ldg

Description

@bluce-ldg

What version of Go are you using (go version)?

$ go version
go1.15.6 linux/amd64

Does this issue reproduce with the latest release?

yes, reproduce with version 1.13、1.15

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=".gitlab.com,.gitee.com"
GONOSUMDB=".gitlab.com,.gitee.com"
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=".gitlab.com,.gitee.com"
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.google.cn"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build926124830=/tmp/go-build -gno-record-gcc-switches"

What did you do?

demo code
package main

/*
#cgo CFLAGS: -I${SRCDIR}/so -fpermissive -std=c99 -std=c++11 -Wall -w -O0 -fpie -pthread -pedantic
//#cgo LDFLAGS: -Wl,-rpath-link=${SRCDIR}/so -L${SRCDIR}/so -ldl -lm -lcpp_clustersdk
#cgo LDFLAGS: -Wl,-rpath-link=${SRCDIR}/so -L${SRCDIR}/so -ldl -lm
//#cgo LDFLAGS: -Wl,-rpath-link=${SRCDIR}/so -I${SRCDIR}/so -L${SRCDIR}/so -ldl -lm -lcpp_clustersdk -lcwcluster
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
//#include <string.h>
//#include <dlfcn.h>

char* _gTestFeatures = NULL;
char* _gHashs = NULL;
char* _gAttrs = NULL;
bool g_init = false;
long g_testSize = 100000;
long g_testCount = 1000000;

typedef struct CMemTest_
{
long _index;
long _count;

char* pFeas;
char* pHashs;
char* pAttrs;

}CMemTest;

CMemTest* gMemTest = NULL;

void PushMemTest(CMemTest* obj)
{
if(!obj->pFeas)
{
obj->pFeas = (char*)malloc(384g_testSize);
obj->pHashs = (char
)malloc(64g_testSize);
obj->pAttrs = (char
)malloc(832g_testSize);
}

    memcpy(obj->pFeas+obj->_index*384, &_gTestFeatures[obj->_index*384], 384);
    memcpy(obj->pHashs+obj->_index*64, &_gHashs[obj->_index*64], 64);
    memcpy(obj->pAttrs+obj->_index*8*32, &_gAttrs[obj->_index*8*32], 8*32);
    obj->_index++;
    obj->_count++;
    if (obj->_index >= g_testSize)
    {
        obj->_index = 0;
    }

}

CMemTest* AllocMemTest()
{
if(gMemTest != NULL)
abort();

gMemTest = (CMemTest*)malloc(sizeof(CMemTest));
gMemTest->_index = 0;
gMemTest->_count = 0;
gMemTest->pFeas = NULL;
gMemTest->pHashs = NULL;
gMemTest->pAttrs = NULL;

}

void FreeMemTest(CMemTest* obj)
{
if(obj->pFeas) free(obj->pFeas);
if(obj->pHashs) free(obj->pHashs);
if(obj->pAttrs) free(obj->pAttrs);
free(obj);
}

int c_Master_TestMem1()
{
if (g_init == false)
{
_gTestFeatures = (char*)malloc(384*(g_testSize+1));
_gHashs = (char*)malloc(64*(g_testSize+1));
_gAttrs = (char*)malloc(832(g_testSize+1));
for (long i = 0; i < g_testSize; i++)
{
for (long j = 0; j < 384; j++)
{
_gTestFeatures[i384+j] = ij;
}
for (long j = 0; j < 64; j++)
{
_gHashs[i64+j] = ij;
}
for (long j = 0; j < 832; j++)
{
_gAttrs[i
832+j] = ij;
}
}

// new std::thread(& {
// uint64_t timeCount = 0;
// while (1)
// {
// #ifndef _WIN32
// malloc_trim(0);
// printf("-----------------\n");
// #endif
// std::chrono::seconds dura(1);
// std::this_thread::sleep_for(dura);
// }
// });
g_init = true;
}

if(gMemTest == NULL)
{
     gMemTest = AllocMemTest();
}

printf("====================================== gMemTest count:%lld =============================\n", gMemTest->_count);

if (0 == (gMemTest->_count % g_testCount))
{
    FreeMemTest(gMemTest);
    gMemTest = NULL;
	printf("\n\n\n\n====================================== reset, press anykey continue =============================\n\n\n\n\n");
	//getchar();

     gMemTest = AllocMemTest();
  //  sleep(1);
}

for (long i = 0; i < 10000; i++)
{
    //if ((i % 1000) == 0)
    //{
    //    //usleep(1000*100);
    //}
    PushMemTest(gMemTest);
}
return 0;

}
*/
import "C"
import (
"fmt"
"net/http"
_ "net/http/pprof"
"os"
)

type DBFeatureJournalnfo struct {
InstType int
FaceId int64
UserId string
PriorLabel int64
GroupIdMapAlgo int32
Feature []byte
ShortFeatureA []byte
ShortFeatureB []byte
ImageUrl string
Qualityscore []byte
FailedModelingInfo string
AddScoreFlag bool
AddScore float32
Time int64
Status int32
TrackId int64
TrackBeginTime int64
TrackEndTime int64
ExtData string
}

var rawFea = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

func GetMemTest() []DBFeatureJournalnfo {
results := make([]DBFeatureJournalnfo, 10000)
result := DBFeatureJournalnfo{}
result.InstType = 1
result.FaceId = 1
result.UserId = "1111111111111111111111111111111111111111111111111"
result.PriorLabel = 1
result.GroupIdMapAlgo = 1

//result.Feature = append(result.Feature, rawFea[0:384]...)
//result.Feature = append(result.Feature, rawFea[0:384]...)

result.Feature = make([]byte, 384, 384*2)
//copy(result.Feature, "11111111111fgdgggggggggggggggggggggggggsgsfddddddddddddddddddddddddddddddddddddddddddddd")
result.Qualityscore = make([]byte, 32*8, 32*8*2)
result.ImageUrl = "ffffffffffffffffffffffffff"

for i := 0; i < 10000; i++ {
	results = append(results, result)
}
return results

}

func main() {
go func() {
http.ListenAndServe("0.0.0.0:8080", nil)
}()

//go func() {
//	http.ListenAndServe("0.0.0.0:8080", nil)
//	debug.FreeOSMemory()
//	time.Sleep(time.Second*5)
//}()

fmt.Println("------------------------------------------")
N := 100000000

for i := 0; ; i++ {
	// step 1 call cgo test function
	C.c_Master_TestMem1()
	// step 2 call go test function
	test := GetMemTest()
	if test == nil {
		os.Exit(1)
	}
}

}

What did you expect to see?

when both call cgo test and go test, It would taking 167Mb of RSS and should be able to stabilize around 170Mb,instead of memory increase several times.

What did you see instead?

  1. We can see from the code,when only call cgo test function(step 1), not call go test function(step 2), It would taking ~142Mb of RSS(resident set size memory) .
    2.when only call go test function(step 2), not call cgo test function(step 1), It would taking ~33Mb of RSS(resident set size memory) .
    3.when both call cgo test and go test, It would taking 167Mb of RSS and then grow to >700Mb
    4.In addition, Using the windows platform,RSS is normal , not as high as linux

Activity

changed the title [-]Memory RSS has been growing abnormally when call cgo and go[/-] [+]cgo: Memory RSS has been growing abnormally when call cgo and go[/+] on Dec 17, 2020
changed the title [-]cgo: Memory RSS has been growing abnormally when call cgo and go[/-] [+]runtime/cgo: Memory RSS has been growing abnormally when call cgo and go[/+] on Dec 17, 2020
added
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
on Dec 17, 2020
added this to the Backlog milestone on Dec 17, 2020
toothrot

toothrot commented on Dec 17, 2020

@toothrot
Contributor
ianlancetaylor

ianlancetaylor commented on Dec 17, 2020

@ianlancetaylor
Contributor

I don't understand what "abnormally" means here. The measure of RSS depends a great deal on what the kernel does and what other processes are running. If the memory does eventually stabilize, then that may be expected. If memory use keeps increasing, there may be a bug in the way that the program is using cgo.

It's not surprising that a program that uses cgo uses more memory than a program that does not use cgo.

added
WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.
on Dec 17, 2020
ianlancetaylor

ianlancetaylor commented on Dec 17, 2020

@ianlancetaylor
Contributor

It's unlikely we'll be able to say anything useful without a test case that we can use to reproduce the problem.

It's likely that you will get better answers on a forum. See https://golang.org/wiki/Questions.

gopherbot

gopherbot commented on Jan 17, 2021

@gopherbot
Contributor

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

locked and limited conversation to collaborators on Jan 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @toothrot@ianlancetaylor@gopherbot@bluce-ldg

        Issue actions

          runtime/cgo: Memory RSS has been growing abnormally when call cgo and go · Issue #43160 · golang/go