草庐IT

c++ - 嵌入式平台上的线程类内存分配异常

coder 2024-02-05 原文

我遇到了一个奇怪的问题,我已经能够找到一些原因,但我仍然看不到原因。也许这里有人可以阐明一些想法?

我在 VxWorks 5.5 之上的 PowerPC 处理器上运行,使用 PPCgnu604 工具链在 C++ 中开发。

我有这样一个类:

class MyClass
{
  public:
    void run( void );
  private:
    CommandMesssageClass command;
    StatusMessageClass status;
};

当我的应用程序启动时,它将动态分配一个 MyClass 实例并生成一个指向其“运行”函数的线程。本质上,它只是坐在那里轮询命令,并在收到命令后返回状态。

请注意,这是该类的简化版本。为简洁起见,省略了许多其他方法和变量。

我看到的问题是,当命令和状态消息都被定义为私有(private)类成员时,我将更改内存中的可用字节,尽管事实上应该没有动态内存分配。这很重要,因为这是在需要确定性和速率安全的过程中发生的。

如果我将一个或两个消息声明移动到运行函数中,它可以正常工作而无需额外分配!

在我对 C++ 声明和内存分配的理解中,我一定遗漏了一些基本知识。我的理解是,我动态实例化的类实例在创建时将完全分配在堆上(包括所有成员变量)。我在这里看到的不同之处在于,将消息声明移至运行函数会将它们放在堆栈上。本例中的堆足以容纳整个类的大小。为什么在使用特定部分之前似乎没有分配足够的内存?

消息类不做自己的动态分配。 (如果他们这样做了,我希望移动声明不会改变这种情况下的行为,我仍然会看到堆大小发生变化。)

为了监控内存分配,我使用了以下 VxWorks memLib(或 memPartLib)调用:

memPartInfoGet( memSysPartId, &partitionStatus );
...
bytesFree = partitionStatus.numBytesFree;

编辑:

澄清一下,MyClass 对象在初始化例程中被实例化和初始化,然后代码进入速率安全处理。在此期间,在通过串行线路接收到命令消息时(与命令或状态消息对象的第一次交互)分配额外的内存(或者更确切地说,可用字节数减少)。这很糟糕,因为动态内存分配是不确定的。

我已经能够按照我所描述的移动类变量来解决这个问题。

最佳答案

I must be missing something fundamental in my understanding of C++ declarations and memory allocation.

我不这么认为。您在上面所说的一切都是正确的——游戏程序员一直严重依赖这种行为。 :-)

Why does it seem not to be allocating enough memory until specific portions are used?

为简洁起见,您省略了类的内容。我有一些调试类似问题的经验,我最好的猜测是那里的某处有一个库函数,实际上,它在进行您不知道的运行时分配。

换句话说,运行时分配在两种情况下都存在,但 MyClass 的两种不同大小意味着 malloc 池的填充方式不同。您可以通过将对象移动到 run() 中的堆栈来证明这一点,但将 MyClass 填充到相同的大小。如果您仍然看到空闲内存下降,那么这与这些对象是在堆上还是堆栈上无关……这是由于 MyClass 的大小而发生的次要影响。

请记住,malloc 很笨重——大多数实现不会为每次调用 malloc 进行一对一的分配。相反,它过度分配内存并将其保留在池中,并在必要时增加这些池。

我不熟悉您的工具链,但嵌入式系统上意外的小分配的典型嫌疑人包括 ctype 函数(语言环境)和日期/时间函数(时区)。

关于c++ - 嵌入式平台上的线程类内存分配异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3392307/

有关c++ - 嵌入式平台上的线程类内存分配异常的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  6. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  7. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  8. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  9. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  10. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

随机推荐