Jump to content
OpenSplice DDS Forum
payne

helloworld standalone example memory leak

Recommended Posts

payne   

Hi all,

I am using 6.7.1 community version to do some tests, I modified the helloworld standalone example under "\examples\dcps\helloworld\cpp", the program will send 300 samples(or called message?) of 300 topics in a second, and  each sample(or called message?) is about 1k byte. After running about 1 hour, the memory usage of the applications(both of sacpp_helloworld_pub.exe and sacpp_helloworld_sub.exe) are more than 1GB, while at the beginning, they were about 6MB. Does anyone know what's the problem? Do I need to do some configurations to avoid the memory leak?

I just use the default ospl.xml as the OSPL_URI value, the content as show below:

 

<OpenSplice>
    <Domain>
        <Name>ospl_sp_ddsi</Name>
        <Id>0</Id>
        <SingleProcess>true</SingleProcess>
        <Description>Stand-alone 'single-process' deployment and standard DDSI networking.</Description>
        <Service name="ddsi2">
            <Command>ddsi2</Command>
        </Service>
        <Service name="cmsoap">
            <Command>cmsoap</Command>
        </Service>
        <DurablePolicies>
            <Policy obtain="*.*"/>
        </DurablePolicies>
    </Domain>
    <DDSI2Service name="ddsi2">
        <General>
            <NetworkInterfaceAddress>AUTO</NetworkInterfaceAddress>
            <AllowMulticast>true</AllowMulticast>
            <EnableMulticastLoopback>true</EnableMulticastLoopback>
            <CoexistWithNativeNetworking>false</CoexistWithNativeNetworking>
        </General>
        <Compatibility>
            <!-- see the release notes and/or the OpenSplice configurator on DDSI interoperability -->
            <StandardsConformance>lax</StandardsConformance>
            <!-- the following one is necessary only for TwinOaks CoreDX DDS compatibility -->
            <!-- <ExplicitlyPublishQosSetToDefault>true</ExplicitlyPublishQosSetToDefault> -->
        </Compatibility>
    </DDSI2Service>
    <TunerService name="cmsoap">
        <Server>
            <PortNr>Auto</PortNr>
        </Server>
    </TunerService>
</OpenSplice>
 

Sorry for my poor English, and thank you for your great help.

 

Share this post


Link to post
Share on other sites

Hi,

It might help if you could share the modified code. What might have happened is that you're creating as many instances (i.e. key-values) as you're creating samples and then perhaps don't unregister() or take() the samples .. in which case the administration-overhead related to any 'instance' might explain your observation.

Regards,

Hans

 

Share this post


Link to post
Share on other sites
payne   

Hi hans,

Thank you for your suggestions. The code I modified is simple, I just make the publisher and subscriber can be always running, and the MAX_NUM is 300. 

How can I unregister() or take() the samples  to reduce the memory usage? BTW, the topic QOS of the example is set RELIABLE_RELIABILITY_QOS and TRANSIENT_DURABILITY_QOS, and I comment out the TRANSIENT_DURABILITY_QOS.

publisher: 

while (true)
  {
      msgInstance.userID = index++;
      msgInstance.timestamp = getCurrentTime();
      for (int i = 0; i < MAX_NUM; i++)
      {
          status = HelloWorldWriter->write(msgInstance, DDS::HANDLE_NIL);
          checkStatus(status, "MsgDataWriter::write");
          os_nanoSleep(delay_1ms);
      }
      
      /*cout << "=== [Publisher] writing a message containing :" << endl;
      cout << "    userID  : " << msgInstance.userID << endl;
      cout << "    Message : \"" << msgInstance.message << "\"" << endl;*/

      os_nanoSleep(delay_700ms);
  }

 

subscriber:

  while (!closed && count < 1500) // We dont want the example to run indefinitely
  {
      for (int i = 0; i < MAX_NUM; i++)
      {
          status = HelloWorldReader->take(msgList, infoSeq, LENGTH_UNLIMITED,
              ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);
          checkStatus(status, "msgDataReader::take");
          for (DDS::ULong j = 0; j < msgList.length(); j++)
          {
              /*cout << "=== [Subscriber] message received :" << endl;
              cout << "    userID  : " << msgList[j].userID << endl;
              cout << "    Message : \"" << msgList[j].message << "\"" << endl;*/
              outfile << "topic" << i << " " << msgList[j].userID << " " << msgList[j].message << /* " " << msgList[j].timestamp << " " << getCurrentTime() << " " << msgList[j].buf <<*/ endl;
              //closed = true;
          }
          status = HelloWorldReader->return_loan(msgList, infoSeq);
          checkStatus(status, "MsgDataReader::return_loan");
      }
    os_nanoSleep(delay_1ms);
    //++count;
  }

IDL:

module Simulator{


    typedef char array1024[1024];

    struct Message {
        long msgId;
        array1024 msg;
    };
#pragma keylist Message msgId
};

 

Share this post


Link to post
Share on other sites

Yeah, I remember that the msgId is a 'key' in the topic so you're creating as many instances as you have key-values.

You could try unregistering the instance after you've written it.

 

Share this post


Link to post
Share on other sites
e_hndrks   

Hi Payne,

To complement Hans' suggestion, you could modify your code in the following ways:

  1. On the Publishing side, follow your write instruction immediately by a corresponding unregister instruction. This instructs the Writer to release all resources allocated to accomodate for future updates to that instance. Not doing this is what causes your memory leak.
    status = HelloWorldWriter->write(msgInstance, DDS::HANDLE_NIL);
    status = HelloWorldWriter->unregister_instance(msgInstance, DDS::HANDLE_NIL);

     

  2. Instruct the Writer to automatically unregister after each Write instruction by setting the (OpenSplice specific) autounregister_instance_delay to 0 on the DataWriterLifecycleQosPolicy in your WriterQos.
        DDS::DataWriterQos wQos;
        result = publisher->get_default_datawriter_qos(wQos);
        result = publisher->copy_from_topic_qos(wQos, tQos);
        wQos.writer_data_lifecycle.autodispose_unregistered_instances = false;
        wQos.writer_data_lifecycle.autounregister_instance_delay = DDS::DURATION_ZERO;
        writer = publisher->create_datawriter(topic, wQos, NULL, DDS::STATUS_MASK_NONE);

     

Regards,

Erik Hendriks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×