标签: stack-size

为什么C#中的堆栈大小正好是1 MB?

今天的PC有大量的物理RAM,但是C#的堆栈大小对于32位进程只有1 MB而对于64位进程只有4 MB(C#中的堆栈容量).

为什么CLR中的堆栈大小仍然如此有限?

为什么它恰好是1 MB(4 MB)(而不是2 MB或512 KB)?为什么决定使用这些金额?

对该决定背后的考虑因素和原因感兴趣.

c# clr stack stack-size

87
推荐指数
2
解决办法
3万
查看次数

为什么最大递归深度我可以达到非确定性?

我决定尝试一些实验,看看我能发现堆栈帧的大小,以及当前执行代码在堆栈中的距离.我们可能会在这里调查两个有趣的问题:

  1. 当前代码的堆栈深度是多少?
  2. 当前方法在到达之前可以达到多少级别的递归StackOverflowError

堆栈当前执行代码的深度

这是我能想到的最好的:

public static int levelsDeep() {
    try {
        throw new SomeKindOfException();
    } catch (SomeKindOfException e) {
        return e.getStackTrace().length;
    }
}
Run Code Online (Sandbox Code Playgroud)

这看起来有点黑客.它生成并捕获异常,然后查看堆栈跟踪的长度.

不幸的是,它似乎也有一个致命的限制,即返回的堆栈跟踪的最大长度为1024.除此之外的任何内容都被削减,因此此方法可以返回的最大值为1024.

题:

有没有更好的方法做到这一点,不是那么hacky并没有这个限制?

对于它的价值,我的猜测是没有:Throwable.getStackTraceDepth()是本机调用,它暗示(但不能证明)它不能用纯Java完成.

确定我们剩下多少递归深度

我们可以达到的等级数量将由(a)堆栈帧的大小和(b)剩余堆栈量确定.让我们不要担心堆栈框架的大小,只需看看我们达到之前可以达到多少级别StackOverflowError.

这是我执行此操作的代码:

public static int stackLeft() {
    try {
        return 1+stackLeft();
    } catch (StackOverflowError e) {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

它的工作令人钦佩,即使它在堆栈剩余量方面是线性的.但这是非常非常奇怪的部分.在64位Java 7(OpenJDK 1.7.0_65)上,结果完全一致:9,923,在我的机器上(Ubuntu 14.04 64位).但Oracle的Java 8(1.8.0_25)给出了非确定性结果:我的记录深度在18,500到20,700之间.

现在为什么它是非确定性的呢?应该有一个固定的堆栈大小,不是吗?并且所有代码对我来说都是确定性的.

我想知道错误捕获是否奇怪,所以我尝试了这个:

public static long badSum(int n) {
    if (n==0)
        return 0;
    else
        return 1+badSum(n-1);
} …
Run Code Online (Sandbox Code Playgroud)

java stack-overflow recursion stack-size java-8

28
推荐指数
1
解决办法
3302
查看次数

好的堆栈深度与某些输入大小成线性比例?

当Java编程(或与此有关的任何其他程序语言),我经常选择递归地解决一些 VS 迭代解决它.递归选项通常比迭代解决方案更优雅,所以我通常会选择递归解决方案.除了一个例外:

担心堆栈溢出如果最大堆栈深度与输入的大小成线性比例(或更差),我倾向于避免递归解决方案.然而我意识到,在许多其他语言中(甚至是针对JVM的那些语言,例如Scala和Clojure),许多算法(例如基本列表算法)通常以递归方式表示,其中最大堆栈深度与列表的长度成比例.(1)那么,我对线性堆栈深度算法中堆栈溢出的担忧是否合理?

TL; DR:什么"堆栈深度复杂度"被认为是合理的?对数复杂度,例如递归二进制搜索,O(log N)肯定没问题,但O(N),O(N log N),O(N 2)怎么样?你通常会在哪里划线?(2)

(1)我意识到这些语言有时支持像@tailrec这样的东西,但这个问题涉及Java,C#等.
(2)注意我并不关心CPU开销等.只是堆栈深度.

c# java algorithm recursion stack-size

13
推荐指数
1
解决办法
187
查看次数

在OS X上使用Clang进行编译时如何增加堆栈大小?

我可以用clang ++指定堆栈大小吗?我找不到任何允许我这样做的编译器选项.我正在使用OS X.

注意:这个问题具体是指Clang,而不是GCC编译器.

macos ld stack-size compiler-options

13
推荐指数
1
解决办法
6414
查看次数

运行一段时间后,可以获得Java中线程使用的实际堆栈大小吗?

这个想法是帮助确定给定Java应用程序的最佳堆栈大小.

使用此信息可以完成的一件事是创建一个堆栈大小的范围表,线程可以在它们退出时修改,并且可以在应用程序退出时定期转储.

编辑:这是在具有真实工作负载的客户机器上运行的环境,我无法获取探查器访问权限.

编辑2:回答一个答案,在(IIRC)每个线程256Kb,我想知道现在有多接近现实需要的东西(我也想知道这个问题可能不是很相关,因为堆栈空间可能是根据需要分配).我们有一个基于消息传递和高度线程化的应用服务器,可运行从ARM手持设备到octo-core Linux,到中型和大型机的所有东西 - 我们可以感受到我们可以交易的位置(以及如果)堆栈空间堆栈在具有许多消息处理程序的系统上.

有一些类似的问题值得关注,但它们是原生的/特定于os的:

java stack-size

12
推荐指数
1
解决办法
9803
查看次数

使用大型预编译头文件时cc1plus.exe崩溃

我在使用MinGW预编译头文件时遇到问题.编译器似乎找到了预编译的头文件,但cc1plus.exe在cc1plus.exe停止工作后立即崩溃.

我知道这可能与cc1plus.exe的低堆栈大小有关,所以我做了以下操作来增加它:

editbin cc1plus.exe /STACK 33554432
Run Code Online (Sandbox Code Playgroud)

我也试着无济于事:

editbin cc1plus.exe /STACK 32768k
Run Code Online (Sandbox Code Playgroud)

然而,这并没有解决它,因为每当我尝试编译我的应用程序时它仍然会崩溃.

顺便说一下,如果重要的话,我正在使用最新的MinGw(gcc v 4.6.2)和最新的Eclipse CDT.

我是否正确增加了cc1plus.exe的堆栈大小?有没有人有任何线索如何继续,因为我阅读了无数的文章和主题,但我现在有点想法.

g ++似乎找到并接受我的预编译头文件:

Building file: ../src/AdvancedOgreFramework.cpp
Invoking: GCC C++ Compiler
g++ -DHAVE_W32API_H -DNO_GCC_PRAGMA -I"C:\DevelopmentTools\workspaces\workspace_cpp
\MyGame\inc" -I"C:\docs\ogre3d\CEGUI\CEGUI-0.7.6\cegui\include\falagard" -I"C:\docs 
\ogre3d\CEGUI\CEGUI-0.7.6\cegui\include\RendererModules\Ogre" -I"C:\docs\ogre3d\CEGUI
\CEGUI-0.7.6\cegui\include" -I"C:\docs\ogre3d\ogre1.8.0_mingw_sdk\OgreSDK_MinGW_v1-8-0
\include" -O0 -g3 -H -Wall -c -Winvalid-pch -MMD -MP -MF"src/AdvancedOgreFramework.d" 
-MT"src/AdvancedOgreFramework.d" -o "src/AdvancedOgreFramework.o" "../src 
/AdvancedOgreFramework.cpp"
! C:\DevelopmentTools\workspaces\workspace_cpp\MyGame\inc/Precompiled.h.gch
Run Code Online (Sandbox Code Playgroud)

这是我作为预构建make运行的makefile,用于生成我的.gch:

C_FLAGS = -O0 -g3 -Wall -c -MMD -MP
INC_PATH = -IC:/docs/ogre3d/ogre1.8.0_mingw_sdk/OgreSDK_MinGW_v1-8-0/include -IC:/docs
/ogre3d/CEGUI/CEGUI-0.7.6-mingw/cegui/include -IC:/docs/ogre3d/CEGUI/CEGUI-0.7.6-
mingw/cegui/include/RendererModules/Ogre -IC:/docs/ogre3d/CEGUI/CEGUI-0.7.6-mingw/cegui
/include/falagard


all: Precompiled.h.gch

@echo 'Finished precompiling headers....'

Precompiled.h.gch: Precompiled.h …
Run Code Online (Sandbox Code Playgroud)

mingw precompiled-headers stack-size

12
推荐指数
1
解决办法
5526
查看次数

Ruby的光纤4kB堆栈大小的后果

纤维对我来说是一个相对较新的概念.我知道每个光纤的堆栈大小限制为4kB,我继续读到我应该"小心"这个.这个限制对现实世界的影响究竟是什么?

编辑:

看起来这个4kB限制毕竟不是一个障碍,它需要光纤本身内的大量局部变量(4,045)才能引发SystemStackError.

count = 0
loop do
  count += 1
  puts count
  varlist = String.new
  count.times do |i|
    varlist += "a#{i} = 1\n"
  end
  s = "fiber = Fiber.new do \n #{varlist} \n end \n fiber.resume"
  eval(s)
end
Run Code Online (Sandbox Code Playgroud)

不是最优雅的代码,但它似乎证明了光纤堆栈的局限性.看起来它只是返回值,局部变量(所有这些变量都包含对堆上对象的引用)和方法调用放在堆栈上.我还没有测试从光纤调用的方法中的局部变量等是否是光纤堆栈的一部分.

编辑2:

修改了上面的代码.看来,被调用方法中的变量等成为光纤堆栈的一部分.如果是这种情况,那么调用深度(即使没有递归)也可能是一个问题,因为方法本身可能需要更多的空间而不是变量(它们似乎是对堆上对象的透明引用).

以下代码在第4,031次迭代时失败,并指示被调用方法中的变量成为光纤堆栈的一部分:

count = 0
loop do
  count += 1
  puts count
  varlist = String.new
  count.times do |i|
    varlist += "a#{i} = 1\n"
  end
  m = "def meth\n #{varlist} \n end"
  eval(m)
  fiber = Fiber.new do
    meth
  end
  fiber.resume …
Run Code Online (Sandbox Code Playgroud)

ruby stack-size fibers

12
推荐指数
1
解决办法
1072
查看次数

Windows上的线程堆栈大小(Visual C++)

是否有调用来确定正在运行的线程的堆栈大小?我一直在寻找MSDN线程函数文档,似乎无法找到一个.

windows stack stack-size

10
推荐指数
2
解决办法
9876
查看次数

计算方法调用堆栈大小以检查StackOverflowException

今天早上我回答了一个与StackoverflowException相关的问题.该人询问何时发生Stackoverflow异常

查看此链接在C#,C++和Java中导致堆栈溢出的最简单方法

所以我的问题是,有没有任何方法可以在程序中动态计算方法调用堆栈大小,然后在调用方法之前应用检查,该方法检查方法调用堆栈是否有空间来容纳它,以防止StackOverflowException.

因为我是一个java人,我正在寻找java,但也寻找与概念相关的解释,没有任何编程语言的限制.

java recursion stack callstack stack-size

10
推荐指数
2
解决办法
3939
查看次数

Cmake改变堆栈大小

有没有办法从Cmake更改堆栈大小?
我只找到一个论坛帖子提到CMAKE_CXX_STACK_SIZE,但找不到该命令的文档。理想情况下,该命令应适用于Visual Studio C++gcc

stack gcc cmake stack-size visual-studio

9
推荐指数
1
解决办法
9229
查看次数