计算方法调用堆栈大小以检查StackOverflowException [英] Computing method call stack size for checking StackOverflowException

查看:165
本文介绍了计算方法调用堆栈大小以检查StackOverflowException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Today morning I answered a question which is related to StackoverflowException . The person has asked when Stackoverflow exception occurs

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

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

So my question is that is there any method by which we can compute the method call stacks size dynamically in our program and then applying a check before calling a method which checks whether method call stack has space to accommodate it or not to prevent StackOverflowException.

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

As I am a java person I am looking for java but also looking for explanation related to the concept without boundation of any programming language.

推荐答案

对于32位JVM,JVM可用的总内存大约为2-4GB,而对于64位JVM(大约4-16EB),这个方块的平方大小约为2-4GB。 JVM将其内存拆分为:

The total memory available to a JVM is about 2-4GB for a 32bit JVM and the square of this for a 64bit JVM (about 4-16EB). The JVM splits it's memory into:


  1. 堆内存(通过JVM选项-Xms和-Xmx控制分配)


  • 构造对象和数组实例

  • 静态类和数组数据(包括包含的对象) / array instances)

  • 线程实例(对象实例,运行时数据和元数据,包括线程对象监视器锁引用)

非堆内存


  • 聚合堆栈内存


    • 每线程堆栈内存(通过JVM选项-Xss控制每线程分配):方法调用帧,参数,返回值,本地声明的原语&对象的引用

    • aggregate stack memory
      • per-thread stack memory (per-thread allocation controlled via JVM option -Xss): method call frames, arguments, return values, locally declared primitives & references to objects

      参见 http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html http://www.yourkit.com/docs/kb/sizes.jsp


      是否有任何方法可以在我们的程序中动态计算方法调用堆栈大小

      Is there any method by which we can compute the method call stacks size dynamically in our program




      1. Java SE / Java EE中没有标准方法来获取每线程堆栈的实际内存使用量。 / li>
      2. 有一些标准方法可以获得聚合的非堆内存: MemoryMxBean.getNonHeapMemoryUsage() 。参考这个不允许你做出动态的代码内决策来避免 StackOverflow 异常

      3. 有标准的方法可以获得调用堆栈没有它的内存使用情况: Thread.getStackTrace() ThreadMxBean.getThreadInfo()& ThreadInfo.getStackTrace()

      1. There's no standard method included in Java SE/Java EE to obtain the per-thread stack actual memory usage.
      2. There are standard methods to obtain the aggregate non-heap memory: MemoryMxBean.getNonHeapMemoryUsage(). Referring to this doesn't allow you to make dynamic in-code decisions to avoid StackOverflow exception
      3. There are standard methods to obtain the call stack without it's memory usage: Thread.getStackTrace() ThreadMxBean.getThreadInfo() & ThreadInfo.getStackTrace()

      我建议您不要在问题中做出建议,因为:


      • 如果没有一些复杂的特定于JVM的API来监视动态线程堆栈内存的使用情况,你就无法做到 - 你会在哪里找到这样的API ??

      • 每个线程堆栈通常相对于整个JVM消耗少量内存,因此通常很容易分配足以满足您的算法(例如,对于Windows 64位JVM默认为128KB堆栈大小,而整个JVM可能预算为2GB内存)

      • 功能非常有限:如果你的逻辑实际上是需要调用一个方法,但由于内存不足你不能,那么你的程序就会被打破。一个 StackOverflow 异常实际上是最好的回复。

      • 你要做的是反 - 设计反模式

        正确的方法是指定程序要求,指定所需的运行时环境(包括最小/需要的内存!),并相应地设计程序以获得最佳性能和内存使用情况。

      • You can't do it without some complex JVM-specific API that instruments/introspects on dynamic thread stack memory usage - where will you find such an API??
      • The per-thread stack normally consumes a tiny amount of memory relative to the entire JVM, so it is usually easy to assign enough to suit your algorithm (e.g. default of 128KB stack size for Windows 64bit JVM whilst 2GB of memory might have been budgeted for the entire JVM)
      • It would be very limited in power: if your logic actually needed to call a method, but you couldn't due to insufficient memory, then your program would be broken at that point. A StackOverflow exception would actually be the best response.
      • What you are trying to do could be an anti-design anti-pattern.
        A "correct" approach would be to specify program requirements, specify required runtime environment (including minimum/needed memory!), and design your program accordingly for optimal performance and memory usage.

      反模式是在设计和开发过程中不考虑这些事情,只是想象一下运行时内省魔术可以涵盖的内容。可能存在一些(罕见的)高性能要求的应用程序,这些应用程序需要在运行时彻底重新排列算法以与发现的资源完全匹配 - 但这是复杂,丑陋和昂贵。

      An anti-pattern is to not think about these things appropriately during design and development and just imagine some runtime introspection magic could cover for this. There may exist some (rare!) high-performance-demanding apps which need to drastically rearrange the algorithm at runtime to exactly match the discovered resources - but this is complex, ugly & expensive.

      即便如此,从-Xss参数驱动动态算法在宏观层面上的变化可能会更好,而不是在微观层面上从代码中某个位置的精确堆栈内存消耗。

      And even then, it would probably be better drive dynamic algorithm changes at a macro-level from the "-Xss" parameter, rather than at a micro-level from the exact stack memory consumption at a location in code.

      这篇关于计算方法调用堆栈大小以检查StackOverflowException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆