我有一个用 c/c++ 编写的程序(守护进程)。它运行完美,但在一段时间后(可能是 5 天、一周、2 周),它会分配大量内存。我不明白代码的哪些部分没有释放分配的内存。启动时内存使用量约为 20-30 兆字节。然后在一段时间后,或者可能发生事件后,它会以每小时 1Mb 的速度缓慢增长,如果不终止,可能会因为没有可用内存而崩溃。
我已经尝试使用 Valgrind 并在它已经分配了大约 500Mb 的内存时以通常的方式关闭了守护进程。关机过程真的很长,但是当它结束时,Valgrind 说没有发现内存泄漏,除了 mysql_init/mysql_close 程序(大约 504 字节肯定丢失)。 Google 表示无需担心此 Mysql 泄漏,并给出了一些内存诊断工具(如 Valgrind)认为这是泄漏的原因。
我真的不知道代码的哪些部分分配内存但仅在程序关闭时释放它。帮我查一下
最佳答案
Valgrind 只检测未删除的指针,或多或少。在不需要时将它们放在身边是另一回事。
首先,所有对象和内存在关闭时被释放。如果存在泄漏,valgrind 会将其检测为未被对象引用的内存等。然而,任何泄漏最终都会被操作系统释放。
如果您正在捕获所有异常 (...) 并且不对它们做任何事情,那么请不要那样做。这是一个常见的原因。
其次,关闭期间调用的析构函数的日志文件可能会有所帮助。也许在 main() 的末尾,设置一个全局标志;设置该标志时调用的任何析构函数都可以输出它们的存在。看看是否有很多不应该存在的对象。
更简单一点,你可以使用一个全局变量,每个ctor可以将它递增1,dtor递减1。如果你发现对象的数量没有保持相对不变,你可以调查哪些是使用类似的技术解决问题。
第三,使用 Boost 及其作用域智能指针来提供帮助,但不要依赖智能指针作为 chalice 。
我遇到了一个可能的潜在问题。对于长时间运行的程序,内存碎片会导致大量内存使用。您可以删除一个 1mb 的对象,然后尝试创建一个 2mb 的对象;创作将在新的空间中进行,因为 1mb 的“空闲 block ”不够大。然后当你创建一个 512kb 的对象时,它可能会进入那个 1mb 对象的空间,只使用 1/2 的可用空间,但是这样你的下一个 1mb 对象就需要在大空间中分配。
不幸的是,由于小对象被分配到持久的地方,这个问题可能会变得很严重。比如说,内存中可能有 50 字节的类,相距 300kb,大概有 100 个,但是不能在该空间中分配 512kb 的对象,因此它会为每个新对象分配额外的 512kb,实际上浪费了 90% 的实际 '免费空间,即使您的程序已经拥有足够多的空间。
这个问题很难作为明确的原因来追查,但如果您检查程序的流程,请寻找小的分配。记住 std::list/vector/etc。都可以导致这个;如果你想制作一个运行数周的大量内存操作的守护进程,使用 reserve() 预分配内存是个好主意。内存池甚至更好。
根据您要投入的时间,您还可以制作(或找到)自定义内存分配器,该分配器也会在对象关闭时报告对象。
关于c++ - 找到巨大的已分配内存块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9981946/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
通过rubykoans.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
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我正在学习http://ruby.railstutorial.org/chapters/static-pages上的RubyonRails教程并遇到以下错误StaticPagesHomepageshouldhavethecontent'SampleApp'Failure/Error:page.shouldhave_content('SampleApp')Capybara::ElementNotFound:Unabletofindxpath"/html"#(eval):2:in`text'#./spec/requests/static_pages_spec.rb:7:in`(root)'
如何将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.你能做的最好的事情是:
如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje