编译器堆空间不足(函数调用栈不够应该怎么办)

2024-08-21 20:40:07 :24

编译器堆空间不足(函数调用栈不够应该怎么办)

大家好,编译器堆空间不足相信很多的网友都不是很明白,包括函数调用栈不够应该怎么办也是一样,不过没有关系,接下来就来为大家分享关于编译器堆空间不足和函数调用栈不够应该怎么办的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!

本文目录

函数调用栈不够应该怎么办

调整一个C程序栈的默认大小可以使用编译选项、连接选项或使用#pragma指令,具体用法视编译器不同,VC下可以使用 /Fnewsize 编译选项设置默认栈大小,其中newsize是以字节为单位,也可以使用/STACK:reserve连接选项,使用#pragma指令的样式如下:#pragma comment(linker, "/STACK:reserve,commit")reserve和commit均以字节为单位,具体查看编译器帮助文档。如果手工模拟函数的递归调用,则有范式可供转换,一般的数据结构书上都有介绍,具体操作难度要视递归调用的复杂度而定,一般样式如下://将初始值压栈while(栈非空){ //取出栈顶元素 //处理该问题 //依据处理条件将子问题分别压栈}也可以使用一个线程来调用,为线程指定栈大小。如果是递归调用导致栈溢出,建议LZ考虑更好的算法,增加栈的大小不是根本办法。

visual studio 编译器的堆空间不足问题的解决(cmake版本)

我们有个自动编译游戏引擎的脚本,这个脚本时间用久了,总是会报如下的错误: fatal error C1060: 编译器的堆空间不足 每次出现这种错误,总是要请人重启机器,重新配置,很耽误时间和精力。 所以本人就在努力寻找一个彻底的解决办法。 想直接要解决方法的朋友可以跳过接下来的两节。 简单网上搜一下,就能搜到参考文献1。 如果你的c++工程不用cmake,参考文献1的方法足以满足你的需求。 但是我们工程比较大,肯定是要用cmake的,所以我就开始尝试各种方法: 通过改工程的cmake文件的方式来让cmake生成的vcxproj工程文件中包含PreferredToolArchitecture属性。 网上找了好久,试了不少办法,还是没用。 发现最终解决方案也是个很有趣的过程,值得记录。 首先我看见PreferredToolArchitecture父节点是PropertyGroup,而PropertyGroup下面有Platform属性,PreferredToolArchitecture和Platform是兄弟属性。 我们的Platform用x64还是win32,都是在cmake命令行里指定的。 所以我就大胆猜测,PreferredToolArchitecture这个属性如果可以通过cmake设置的话,大概率也是在cmake的命令行中设置! 接着,就是小心求证的过程,先执行: cmake --help 通过阅读帮助文档,辅以简单的排除法,我觉得toolset-name这个属性很可能是我要的,于是谷歌: cmake toolset name 从而找到了文档2,在文档2中发现了host=x64这个东西,但是我还不知道怎么用!于是继续搜索:cmake host=x64 找到了文档3,然后修改我们的编译脚本,加入这个编译选项,重新cmake,果然,出现了vcxproj文件中看到了PreferredToolArchitecture x64属性! 感觉成功了90%,编译工程,打开任务管理器,观察进程名称,发现c++编译器都是64位的,遂大功告成。 问题的本质就是windows操作系统visual studio的默认cpp编译器是32位的,所以最大内存是4G,就容易导致编译器内存不足。 有问题的cmake指令如下: 使用64位的cpp编译器的解决方法如下: 注意: cmake的GUI并没有-T host的选择,当然最新版的GUI可能也会加这个。。 还有另一种方法,添加环境变量: set PreferredToolArchitecture=x64 虽然用了64位的cpp编译器,过了一段时间,还是报堆空间不足的问题。 据观察,物理内存占用率100%,所以考虑利用空闲的磁盘空间,增大机器的虚拟内存。 ***隐藏网址*** 物理内存只有32G,以前的虚拟内存是6G,我利用空闲磁盘,增大虚拟内存到100G!

tomcat编译内存溢出怎么解决

JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。 一、内存溢出类型 1、java.lang.OutOfMemoryError: PermGen space JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。 PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。 一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况) set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m 2、java.lang.OutOfMemoryError: Javaheap space 第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。 注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。 垃圾回收GC的角色 JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收: 当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。 根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。 为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收, 一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。 二、JVM内存区域组成 简单的说java中的堆和栈 java把内存分两种:一种是栈内存,另一种是堆内存 1、在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配; 2、堆内存用来存放由new创建的对象和数组在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理 堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢; 栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。 java堆分为三个区:New、Old和Permanent GC有两个线程: 新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn java栈存放 栈调整:参数有+UseDefaultStackSize -Xss256K,表示每个线程可申请256k的栈空间 每个线程都有他自己的Stack 三、JVM如何设置虚拟内存 提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。 提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。 默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。 提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。 简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制, 这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了 提示:注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。 提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC ,大大降低了性能 JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64; 由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 解决方法:手动设置Heap size 修改TOMCAT_HOME/bin/catalina.bat 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m" 四、性能检查工具使用 定位内存泄漏: JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。 1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位

IAR中的问题解决方法求解

IAR中的问题解决方法求解很显然你没有使能寄存器的位定义。方法如下:Project ——》 Option ——》 General Options ——》 System(如下图所示),勾选Enable bit definitions in I/O-Include files即可2.MCU型号选择如果和我一样都次都是以空工程创建的话,不过忘了第一步先进Project ——》 Option ——》 General Options ——》 Target选择所使用的MCU型号,不然编译免不了要报错,如下图所示。3. 堆栈大小今天下午编译一个程序,0错误0警告,挺好,可一运行就跑飞,根本不能正常运行。其实是我没有正常设置堆栈大小导致的这种问题,尤其是在写大工程时,这种错误出现的概率很高。GCC和IAR分配堆栈的方式不同,IAR先分配堆栈空间,相当于定义一个全局数组为堆栈空间,堆栈初始为堆栈空间最高地址;GCC不用先分配堆栈,自动把RAM剩余空间作为堆栈空间,堆栈初始为RAM最高地址。先编译看看自己的程序用了多少ram,在看看总共有多少ram。然后Project ——》 Option ——》 Linker ——》 List选择生成LIST文件,并包含stack选项,如下图所示。在./Debug/list目录下,得到.map(可能是.lst等其他格式)文件,用记事本打开,找到以下内容:***************************************** ** CALL GRAPH ** *****************************************-》Sub-tree of type: Interrupt function tree that does not make: indirect callsCSTACK| Stack used (prev) : 0000000001 int_T0_OV| Stack used (prev) : 00000000| + function block : 0000000C......(省略N行)01 main| Stack used (prev) : 0000003A| + function block : 00000000《-Sub-tree of type: Function tree| Stack used : 000000E2找到最大的Stack used,我的就是000000E2,这就是用到的最大的堆栈空间,保守一点,我设置成0x100字节,没有超过剩余RAM,再重新编译,运行,仿真器没有堆栈不足警告,程序也能正常运行了。如下图所示:4. 查看汇编相信一个优秀的单片机软件工程师都多多少少会去看看编译器的汇编代码,看看有没有什么问题或者看看编译器有没有自作聪明的做些什么Project ——》 Option ——》 C/C++ complier ——》 List,勾选output assembler files,编译后则生成离线汇编代码文件此时在工程目录下的Debug--》List即可看到所有参加编译的C文件对应的汇编文件,后缀名为*.s905.内联函数inline函数传统上只有C++支持,但IAR EW也支持在C代码中使用inline.#pragma inline:建议编译器对紧随其后的函数进行inline处理#pragma inline = forced: 强制编译器对紧随其后的函数进行inline处理复制代码/***************************** 错误描述 ******************************************/// tft.c中定义内联函数#pragma inline = forced //强制inlinevoid TFT_Write_Colour(const RGB_COLOUR *rgb){ //...code....}// tft.h中声明函数void TFT_Write_Colour(const RGB_COLOUR *rgb);// main.c中调用函数// 编译报错:main中引用了未定义的外部函数TFT_Write_Colour。/***************************** 解决办法 ******************************************/// tft.h中“定义函数”#pragma inline = forced //在IAR EW430中,这里必须用强制inline;用inline可能导致编译器忽略内联,而定义成普通函数而出错。void TFT_Write_Colour(const RGB_COLOUR *rgb){ //...code....}// main.c中包含tft.h,并调用函数// 结果:编译正确复制代码6. 如何把变量定义到flash空间unsigned char __flash temptab = {1,2,3,4,5}; 《br》__flash unsigned char a @ 0x8; // 定义变量存放在flash 空间0X08单元7. 关于内存模型AVR 微控制器的其中一个特点是它有一种存储器访问方法均衡了“cheap access limited to small memory areas”与“more expensive accessmethods that can access any location in memory”。在AVR_IAR C/C++编译器中,通过选择某种存储模式(memory model),可设置一些访问方法为默认的存储器访问方法(default memory accessmethod)。共有三种可用的存储模式——Tiny,Small 和Large。你的处理器选项决定了哪些模式可以使用。如果你不指定一种存储模式,则编译器自动设定-v0、-v1、-v2、-v3、-v5 选项下的默认方法为Tiny,-v4 和-v6 选项下的访问方法为Small。  8. 关于生成文件格式的设置如图,在linker -》 outpu -》other中可设置相应的输出文件格式.比如要生成bin格式,选择raw-binary就可以了, 如果是要生成hex格式,那么可以选intel-extern ,不过这个时候文件扩展名是*.a90,可以把"Override default " 打钩,然后修改后缀名为hex就行了.

msp430编译器的堆栈在哪里设置

我用的是IAR 4.11b for MSP430,4.11里面改堆栈是在你工程的Options里面。首先在Workspace窗口右键单击你的工程,然后选择第一项"Options",或者选在上面菜单中选择Project-》Options也可以进入这个选项。在Options里面第一个General Options中,有一堆选项卡,第五个选项卡(就是Library Options再向右一个)就是Stack/Heap,用来调整堆和栈的大小的。调的时候先在Override Default前面打钩。如果你用的是地址线没有扩展的MCU版本,则只有Stack Size 和Heap Size 两个选项可以选择。如果你是用的是较新的F5系列扩展地址线版本MCU,则还可以设置Data20 Heap Size.具体怎么设要根据你的应用需求。如果你需要自己申请用来存放Data20类型的数据,就需要把Data20 Heap Size设大一点。如果存放普通的数据那么只需要更改Stack Size和Heap Size。Stack和Heap的区别有问题吗?如果不清楚的话上百度输入“堆和栈的区别”自己看吧。根据你的应用到底是堆空间要求多一些,还是栈空间要求多一些,给Stack Size和Heap Size分配不同大小的Size。别的版本的IAR我也没用过,有什么问题在线交流吧。希望对你有帮助!

保持性存储器不足,无法进行编译

可以尝试以下几种方法:1、增加保持性存储器(heapmemory)可以在编译器或IDE设置中增加可用的保持性存储器(heapmemory)的大小,以便程序能够分配更多的空间创建对象和运行程序。2、优化代码,减少内存使用量可以尝试优化程序代码,减少内存使用量。例如,避免创建不必要的对象或使用过多的大数组。3、关闭其他应用程序在编译程序时,关闭其他应用程序,尤其是那些需要占用大量内存的程序,以释放计算机的保持性存储器(heapmemory)。

函数调用栈不够应该怎么办的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于函数调用栈不够应该怎么办、函数调用栈不够应该怎么办的信息别忘了在本站进行查找哦。

编译器堆空间不足(函数调用栈不够应该怎么办)

本文编辑:admin
Copyright © 2022 All Rights Reserved 威海上格软件有限公司 版权所有

鲁ICP备20007704号

Thanks for visiting my site.