Java DDS无界序列导致内存不足错误

Java DDS无界序列导致内存不足错误,java,intellij-idea,data-distribution-service,rti-dds,Java,Intellij Idea,Data Distribution Service,Rti Dds,我是DDS新手,正在尝试用Intellij IDEA编写一个简单的Java程序,该程序由3部分组成: 发送数据的客户端模拟器 我的程序模拟器从客户端接收数据,对其进行操作并将其发送回客户端 读取被操纵数据的客户端模拟器 在我的示例中,我试图发送的所有数据都是一个简单的字符串 我使用RTI代码生成器自动生成大部分代码 没有和unboundedSupport标志(字符串限制为255个字符),一切正常。但是,当应用unbounddsupport标志时,我遇到以下内存不足错误: java.lang.Ou

我是DDS新手,正在尝试用Intellij IDEA编写一个简单的Java程序,该程序由3部分组成:

  • 发送数据的客户端模拟器
  • 我的程序模拟器从客户端接收数据,对其进行操作并将其发送回客户端
  • 读取被操纵数据的客户端模拟器
  • 在我的示例中,我试图发送的所有数据都是一个简单的字符串

    我使用RTI代码生成器自动生成大部分代码

    没有和
    unboundedSupport
    标志(字符串限制为255个字符),一切正常。但是,当应用
    unbounddsupport
    标志时,我遇到以下内存不足错误:

    java.lang.OutOfMemoryError: Java heap space
        at com.rti.dds.cdr.CdrBuffer.<init>(Unknown Source)
        at com.rti.dds.cdr.CdrOutputStream.<init>(Unknown Source)
        at com.rti.dds.cdr.CdrOutputStream.<init>(Unknown Source)
        at com.rti.dds.cdr.CdrOutputStream.<init>(Unknown Source)
        at com.rti.dds.infrastructure.EntityImpl.DDS_Entity_enable(Native Method)
        at com.rti.dds.infrastructure.EntityImpl.enable(Unknown Source)
        at com.rti.dds.infrastructure.NativeFactoryMixin.create_entityI(Unknown Source)
        at com.rti.dds.subscription.SubscriberImpl.create_datareader(Unknown Source)
        at json_dds.JsonMessageSubscriber.<init>(JsonMessageSubscriber.java:71)
        at results_consumers.ResultsConsumersMain.main(ResultsConsumersMain.java:10)
    create_datareader error
    
    这是我的主程序(第10行是subscriber1的初始化):

    这是我的ClientResultsConsumer类:

    public class ClientResultsConsumer implements Consumer {
    
      @Override
      public void consume(String msg) {
        System.out.println("Client results consumer got " + msg);
      }
    }
    
    这是我的JsonMessageSubscriber类(第71行是subscriber.create_datareader():

    不幸的是,除了限制序列大小外,我没有找到解决方法,但我明白,将其限制到足够大的数量将解决我的问题,它也将需要大量内存,我希望它不会占用超过每条消息所需的最小值

    任何帮助都将不胜感激,
    感谢使用-unboundedSupport时,必须在QoS文件中设置一些内存阈值。用户手册中介绍了这些阈值,它们定义了动态分配样本内存或从预分配源重新使用样本内存的阈值。必须在DataReader和Data Manager中设置这些阈值作家


    这些阈值的设置实际上取决于您的数据大小,根据您的描述,我没有足够的信息为您提供在您的场景中有意义的示例。基本上,您不希望为每个示例动态分配内存。这可能会影响性能,具体取决于您的数据速率。您需要要选择大多数样本使用预分配内存的值。请参阅用户手册“”部分下提供的示例是一种视频流,其中包含较大的较不频繁的I帧和较小的较频繁的P帧。您可以查看该部分以及相应的示例XML文件。

    我使用示例解决了此问题

    只需将自动生成的qos文件路径传递给订阅服务器/发布服务器构造函数,然后在初始化域参与者之前写入这些行(这与上面链接中提供的示例不同,提供的示例对我不起作用):


    我花了一段时间才回到这个问题上。我找到了自动生成的USER_QOS_PROFILES.xml文件和相关阈值。但是,在您提供的第一个链接中,没有定义阈值数字。尝试使用第三个链接(33792)中的数字时,我遇到了相同的错误。可能我的QOS文件的起始位置不正确?
    public static void main(String... args) {
        ClientResultsConsumer clientResultsConsumer = new ClientResultsConsumer();
        JsonMessageSubscriber subscriber1 = new JsonMessageSubscriber(0, clientResultsConsumer,
                                                                                   Topics.CLIENT_TOPIC_OUTPUT_1);
        subscriber1.consume();
        ClientResultsConsumer2 clientResultsConsumer2 = new ClientResultsConsumer2();
        JsonMessageSubscriber subscriber2 = new JsonMessageSubscriber(0, clientResultsConsumer2,
                                                                                   Topics.CLIENT_TOPIC_OUTPUT_1);
        subscriber2.consume();
        ClientResultsConsumer3 clientResultsConsumer3 = new ClientResultsConsumer3();
        JsonMessageSubscriber subscriber3 =
            new JsonMessageSubscriber(0, clientResultsConsumer3, Topics.CLIENT_TOPIC_OUTPUT_2);
        subscriber3.consume();
      }
    
    public class ClientResultsConsumer implements Consumer {
    
      @Override
      public void consume(String msg) {
        System.out.println("Client results consumer got " + msg);
      }
    }
    
    public class JsonMessageSubscriber implements DataConsumer {
    
      ExecutorService executor = Executors.newSingleThreadExecutor();
    
      public JsonMessageSubscriber(int domainId, Consumer consumer, String topicName) {
    
        DomainParticipant participant = DomainParticipantFactory.TheParticipantFactory
            .create_participant(domainId,
                                DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
                                null /* listener */,
                                StatusKind.STATUS_MASK_NONE);
        if (participant == null) {
          System.err.println("create_participant error\n");
          System.exit(-1);
        }
    
        // --- Create subscriber --- //
    
                /* To customize subscriber QoS, use
                the configuration file USER_QOS_PROFILES.xml */
    
        Subscriber subscriber = participant.create_subscriber(
            DomainParticipant.SUBSCRIBER_QOS_DEFAULT, null /* listener */,
            StatusKind.STATUS_MASK_NONE);
        if (subscriber == null) {
          System.err.println("create_subscriber error\n");
          System.exit(-1);
        }
    
        // --- Create topic --- //
    
        /* Register type before creating topic */
        String typeName = JsonMessageTypeSupport.get_type_name();
        JsonMessageTypeSupport.register_type(participant, typeName);
    
                /* To customize topic QoS, use
                the configuration file USER_QOS_PROFILES.xml */
    
        Topic topic = participant.create_topic(
            topicName,
            typeName, DomainParticipant.TOPIC_QOS_DEFAULT,
            null /* listener */, StatusKind.STATUS_MASK_NONE);
        if (topic == null) {
          System.err.println("create_topic error\n");
          System.exit(-1);
        }
    
        // --- Create reader --- //
    
        DataReaderListener listener = new JsonMessageListener(consumer);
    
                /* To customize data reader QoS, use
                the configuration file USER_QOS_PROFILES.xml */
    
        JsonMessageDataReader reader = (JsonMessageDataReader)
            subscriber.create_datareader(
                topic, Subscriber.DATAREADER_QOS_DEFAULT, listener,
                StatusKind.STATUS_MASK_ALL);
        if (reader == null) {
          System.err.println("create_datareader error\n");
          System.exit(-1);
        }
      }
    
      // -----------------------------------------------------------------------
    
      @Override
      public void consume() {
        final long scanTimeMillis = 1000;
        Runnable task = () -> {
          while (true) {
            try {
              TimeUnit.MILLISECONDS.sleep(scanTimeMillis);
            } catch (Exception e) {
              System.err.println(e.getMessage());
            }
          }
        };
        executor.submit(task);
      }
    }
    
    DomainParticipantFactoryQos factoryQos = new DomainParticipantFactoryQos();
    DomainParticipantFactory.TheParticipantFactory.get_qos(factoryQos);
    factoryQos.profile.url_profile.add(0, qosPolicyPath);
    factoryQos.profile.url_profile.setMaximum(1);
    DomainParticipantFactory.TheParticipantFactory.set_qos(factoryQos);