Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dds_take memory leak #2102

Open
gxl1457628736 opened this issue Oct 9, 2024 · 9 comments
Open

dds_take memory leak #2102

gxl1457628736 opened this issue Oct 9, 2024 · 9 comments

Comments

@gxl1457628736
Copy link

static void subscriber_available_callback(dds_entity_t reader, void *arg)
{
    #define MAXCOUNT 10
    int samples_received;
    void *samples[MAXCOUNT] = { nullptr };
    dds_sample_info_t info[MAXCOUNT];
    std::memset(info, 0, sizeof(info));
    // samples[0] = Sensor_GNav_tGNavSensor__alloc();
    CIoxSensorCore *IoxSensorCore = (CIoxSensorCore *)arg;

    samples_received = dds_take(reader, samples, info, MAXCOUNT, MAXCOUNT);
    if (samples_received < 0)
    {
        printf("dds_take: %s\n", dds_strretcode(-samples_received));
    }
    for (int i = 0; i < samples_received; i++)
    {
        if (info[i].valid_data)
        {
            // 获取topic名
            auto iter = IoxSensorCore->m_reader_map.find(reader);

            if (iter != IoxSensorCore->m_reader_map.end())
            {
                char *topic_name = const_cast<char *>(iter->second.c_str());
                printf("topic[%s] trigger callback.. index[%d]\n", topic_name, info[i].source_timestamp);

                // 调用用户提供的回调函数
                if (IoxSensorCore->m_subscriber_callback != NULL)
                {
                    IoxSensorCore->m_subscriber_callback(info[i].source_timestamp, (void *)samples[i], topic_name);
                }
                
            }
        }
    }
    // dds_return_loan(reader, samples, samples_received);//dds_take完后一定要调用此函数进行内存回收
}

When using cycleddds for shared memory communication, the dds_take call caused a memory leak. After trying, it is necessary to manually call dds_turn_Loan for memory recovery. But I noticed that the example/shmsubscriber. c you provided did not call this function for memory recycling processing
But when I was writing data in publisher, I didn't call dds_land_stample, and I'm not sure if this is the cause

@t0ny-peng
Copy link
Contributor

t0ny-peng commented Oct 9, 2024

Running into the same issue. Let me create a snippet to demonstrate that

@gxl1457628736
Copy link
Author

I am currently using the release 0.10.5 branch's cycleddds, but the dds_rit_impl you provided is the content of the master branch. So should I use the master or release branch of the cyclone?

@gxl1457628736
Copy link
Author

Sensor_LidarRSI_tLidarRSI sensor_data;
		// 拷贝数据
		sensor_data.ScanNumber = LidarRSI->ScanNumber;
		sensor_data.ScanTime = LidarRSI->ScanTime;
		sensor_data.nScanPoints = LidarRSI->nScanPoints;

		// 动态指针数据拷贝赋值
		sensor_data.ScanPoint._length = LidarRSI->nScanPoints;
		sensor_data.ScanPoint._maximum = LidarRSI->nScanPoints;
		sensor_data.ScanPoint._release = false;
		sensor_data.ScanPoint._buffer = (Sensor_LidarRSI_tScanPoint *)dds_alloc(LidarRSI->nScanPoints * sizeof(tScanPoint));
		if (sensor_data.ScanPoint._buffer != NULL)
		{
			// 拷贝指针数据
			memcpy(sensor_data.ScanPoint._buffer, LidarRSI->ScanPoint, LidarRSI->nScanPoints * sizeof(tScanPoint));
		}

		memcpy(sensor_data.t_ext, LidarRSI->t_ext, sizeof(sensor_data.t_ext));
		memcpy(sensor_data.rot_zyx_ext, LidarRSI->rot_zyx_ext, sizeof(sensor_data.rot_zyx_ext));


		// 写序列化数据到内存
		dds_return_t status = dds_write_ts(writer, &sensor_data, (dds_time_t)index);
		if (status < 0)
		{
			printf("dds_write: %s\n", dds_strretcode(-status));
		}

Does shared memory support the transmission of dynamic data in this way, where the structure is a sequence type

@yanzhang920817
Copy link

你的问题解决了吗?

@gxl1457628736
Copy link
Author

你说的是哪个问题,可以加个联系方式交流一下吗?v:17854263171

@t0ny-peng
Copy link
Contributor

I think I'm seeing the same issue here. An reproducible snippet can be found in the latest commit in my fork that uses dds_take for the HelloWorld example(and with dds_return_loan afterward)
t0ny-peng@280686c

https://github.com/t0ny-peng/cyclonedds/tree/bug/dds_take_memory_leak

mkdir build install
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_FLAGS="-O3" -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -DBUILD_IDLC=ON -DBUILD_DDSPERF=ON -DENABLE_TYPELIB=ON -DENABLE_TYPE_DISCOVERY=ON -DENABLE_TOPIC_DISCOVERY=ON ..

cmake --build . -j 12 --target all

Then run the publisher and subscriber in different terminals.

# Terminal 1
./bin/HelloworldPublisher
# Terminal 2
./bin/HelloworldSubscriber

I'm not sure if this is a leak in dds_take. Could it be that the some QoS settings leads to this memory increase? Sorry I'm buried with tons of work and can't look into the cause right now. Will revisit it later this quarter if it's still not solved.

@t0ny-peng
Copy link
Contributor

Memory footprint:

 [DESKTOP]➜ /home/<name> while true; do date; smem -r | grep 1496084; sleep 10; done;
Mon 14 Oct 2024 10:12:29 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      768     1528     4748
Mon 14 Oct 2024 10:12:40 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      780     1540     4760
Mon 14 Oct 2024 10:12:50 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      784     1544     4764
Mon 14 Oct 2024 10:13:01 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      796     1556     4776
Mon 14 Oct 2024 10:13:11 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      804     1564     4784
Mon 14 Oct 2024 10:13:22 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      812     1572     4792
Mon 14 Oct 2024 10:13:32 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      820     1580     4800
Mon 14 Oct 2024 10:13:43 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      832     1592     4812
Mon 14 Oct 2024 10:13:54 PM PDT
1496084 <name> ./bin/HelloworldSubscriber         0      840     1600     4820

@gxl1457628736
Copy link
Author

I solved the memory leak problem by joining dds_turn_roan, but there were errors caused by iceoryx: ""ICEORYX error! POPO__CHUNK_SENDER_INVALID_CHUNK_TO_SEND_FROM_USER" or "POSH__MEMPOOL_POSSIBLE-DOUBLE_FREE". I couldn't solve it, so I gave up using shared memory and used UDP with cycleddds for data transmission between different processes on the same host

@t0ny-peng
Copy link
Contributor

t0ny-peng commented Oct 15, 2024

@gxl1457628736 Hm? I'm calling dds_return_loan too but the memory keeps increasing. Could you please try the Helloworld snippet I created to see if memory leak can be observed?

Btw I have removed the @key specifier in the IDL to avoid CycloneDDS treating each message as with unique key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants