eclipse-cyclonedds / cyclonedds

Eclipse Cyclone DDS project
https://projects.eclipse.org/projects/iot.cyclonedds
Other
888 stars 363 forks source link

dds_take memory leak #2102

Open gxl1457628736 opened 1 month ago

gxl1457628736 commented 1 month ago
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 commented 1 month ago

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

gxl1457628736 commented 1 month ago

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 commented 1 month ago
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 commented 1 month ago

你的问题解决了吗?

gxl1457628736 commented 1 month ago

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

t0ny-peng commented 1 month ago

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) https://github.com/t0ny-peng/cyclonedds/commit/280686c0441b1309a339d7af01a6f284ef45eec6

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

@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.