计算方法调用堆栈大小,用于检查stackoverflowException

发布于 2025-02-07 07:26:57 字数 487 浏览 2 评论 0 原文

今天早上,我回答了一个与StackoverFlowException有关的问题。该人询问了stackoverflow异常何时发生,

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

因此,我的问题是有任何方法,我们可以在程序中动态地调用call stacks大小在我们的程序中,然后在调用一个调用之前进行检查检查方法呼叫堆栈是否有空间可容纳它的方法,以防止stackoverflowException。

作为我是一个爪哇人,我正在寻找爪哇,但也寻找与该概念相关的解释,而没有任何编程语言的界限。

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

See this link Simplest ways to cause stack overflow in C#, C++ and Java

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

醉态萌生 2025-02-14 07:27:00

对于32位JVM而言,JVM可用的总内存约为2-4GB,而64位JVM(约4-16EB)的平方为正方形。 JVM将其内存分为:

  1. HEAP内存(通过JVM选项控制-XMS和-XMX)

    • 构造对象和数组实例
    • 静态类和数组数据(包括包含对象/数组实例)
    • 线程实例(对象实例,运行时数据&元数据,包括线程对象监视器锁定引用)
  2. 数据&元数据包括线程
    • 聚合堆栈内存
      • 每线堆栈内存(通过JVM选项控制的每线分配-XSS):方法调用框架,参数,返回值,本地声明为原始&引用对象
    • 静态常数(原始)
    • 字符串实例池
    • Java代码:加载类和元数据
    • JVM内部使用内存(JVM代码和数据结构)

请参见 http://docs.oracle.com/javase/7/docs/papi/java/java/java/java/lang/lang/management/memorymoymorymoymorymxbean.html

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

  1. 在Java SE/Java EE中没有包含标准方法来获得每线程堆栈实际的内存用法。
  2. 有标准方法可以获得汇总的非HEAP内存: memoryMxBean.getNonheapMemoryUsage()。参考此内容不允许您做出动态的编码决策以避免 stackoverflow 例外,
  3. 有标准方法可以获取呼叫堆栈而无需内存使用: thread.getStackTrace() /docs.oracle.com/javase/7/docs/api/java/lang/management/threadmxbean.html#getthreadinfo%28long,%20Int%29“ rel =“ noreferrer”>“ noreferrer”> threadmxbean.getThreadInfo() ;

我建议您不要在问题上做您建议的事情,因为:

  • 如果没有某些复杂的JVM特定的API,可以使用动态线程堆栈存储器使用来启发/内省 - 您在哪里可以找到这样的API?
  • 每个堆栈通常相对于整个JVM消耗少量的内存,因此通常很容易分配足够的分配以适合您的算法(例如,Windows 64bit JVM的128KB堆栈尺寸默认为2GB,在整个JVM中可能已经预算了内存的预算),
  • 这将非常有限:如果您的逻辑实际需要调用方法,但是由于内存不足,您无法造成的,那么您的程序将在此时被打破。 stackoverflow 异常实际上是最好的响应。
  • 您要做的事情可能是反设计抗模式
    “正确”的方法是指定程序要求,指定所需的运行时环境(包括最小/所需的内存!),并相应地设计程序以进行最佳性能和内存使用。

    一个反模式是在设计和开发过程中不适当地考虑这些事情,然后想象一下某些运行时的内省魔术可以为此涵盖。可能存在一些(罕见的!)高性能的应用程序,需要在运行时大量重新安排算法以与发现的资源完全匹配 - 但这很复杂,丑陋&昂贵的。

    ,即使那样,也可能是从“ -xss”参数上以宏级别更改动态算法,而不是从代码中的一个位置的确切堆栈内存消耗中的微观级别。

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. Heap Memory (allocation controlled via JVM options -Xms and -Xmx)

    • constructed object and array instances
    • static classes and array data (including contained object/array instances)
    • thread instances (object instances, runtime data & metadata including thread object monitor lock references)
  2. Non-Heap Memory

    • 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
    • static constants (primitives)
    • String instance pool
    • java code: loaded classes and metadata
    • JVM internal-use memory (JVM code and data structures)

See http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html and 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. 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()

I recommend that you don't do what you suggest in the question because:

  • 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.

    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.

烟柳画桥 2025-02-14 07:27:00

我希望我猜你真正要问什么。起初,我以为您是在问您的电话要接到多少个。换句话说,我认为您想知道根据您当前的方法情况触发此例外的可能性。然后我决定您真的想找出您必须玩的堆栈深度。在这种情况下,这里有另一个似乎可以解决这个问题的堆栈流行问题。 Java称为堆栈的最大深度是多少? /a>

这告诉您如何将其设置为Java命令行参数(对Java,而不是您的程序)。

无论哪种方式,我都想指出,当我无休止的递归时,堆栈溢出主要发生在我身上。我曾写过(当然是错误地)自称的方法,当问题解决时,我本来打算停止,但是以某种方式从未达到终止状况。这将方法调用一遍又一遍地堆叠到超过最大值。不是我的想法。

我希望有帮助。

I hope I am guessing what you are really asking. At first I thought you were asking how many calls deep your call was about to be. In other words, I thought you wanted to know how likely you were to trigger this exception, based on your current method circumstances. Then I decided you really wanted to find out how much stack depth you have to play with. In that case, there is another stack-overflow question that seems to address this, here. What is the maximum depth of the java call stack?

This tells you how to set that as a java command line parameter (to java, not your program).

Either way, I'd like to point out that stack overflow has mainly happened to me when I had an endless recursion. I had written methods (by mistake, of course) that called themselves, and were meant to stop when the problem got solved, but somehow the termination condition was never reached. This puts the method invocation onto the stack over and over until the max is exceeded. Not what I had in mind.

I hope that helps.

心清如水 2025-02-14 07:27:00

据我所知,Java中的堆栈极限非常抽象,并且不打算进行测量。实际上,我怀疑堆栈尺寸会根据记忆等几个因素而因机器而异。

除了无限的循环 /递归外,我从来没有得到过一些程序来投掷堆栈溢出例外。我正在挠头,试图弄清楚如何在没有无限循环的情况下如何投掷堆栈溢出异常。如果您的程序调用了许多方法,那么它很可能同时创建对象,并且您比没有无限循环的堆栈溢出异常更有可能收到外在错误的错误。

实际上,堆栈限制的重点可能会限制您的正常运作能力? Java有内存限制,可以照顾您的资源过度。堆栈溢出的目的是捕获运行AMOK并需要捕获的循环/递归。

我要提出的观点是:如果堆栈溢出异常困扰您的设备测试,则应该检查这些循环/递归功能是否有些失控的行为。通话堆栈非常非常长,我怀疑您自然而然地到达了它。

As far as I am aware, the stack limit in Java is quite abstract and not intended for measuring. In fact, I suspect that the stack size would vary from machine to machine, based on several factors such as memory.

I've never gotten a program to throw a stack overflow exception except for infinite loops / recursion. I'm scratching my head trying to figure out how it would even be possible to throw a stack overflow exception without an infinite loop. If your program is calling that many methods, then it is likely creating objects simultaneously, and you are much more likely to receive an OutOfMemory error than a stack overflow exception without infinite loop.

In fact, what the heck would be the point of a stack limit that could limit your ability to function properly? Java has memory limits to take care of you going overboard with resources. The purpose of stack overflow is to catch loops/recursion that have run amok and need to be caught.

The point I'm trying to make is: if stack overflow exceptions plague your unit testing, you ought to check those loops/recursive functions for some out of control behavior. The call stack is very, very long and I doubt you've reached it naturally.

天邊彩虹 2025-02-14 07:27:00

好吧,您可以使用Microsoft C ++编译器中的C中使用类似的内容:
一个特定的功能(我不记得名称),该功能在每个启动和结束功能上自动称为。

另外,您可以通过增加并在开始函数和结束函数之前通过增加并减少全局计数器来计算呼叫和子电量的数量。

例如,使用Microsoft .NET,您可以插入一些函数调用以增加并在每个调用上减少全局计数器。这是JIT设计的。

您也可以使用NOSQL数据库来存储您的呼叫。

另外,还有另一件事:使用自动跟踪调用的日志系统。

另外,当您的呼叫堆栈已满时,有时是由递归功能引起的。使用几行代码和一个对象,您可以在每个调用上的每个函数上存储一些传播。
该解决方案也可用于检测任何功能的特殊事物:“谁在打电话给我?”

另外,由于Java是生成的字节代码,因此您可以检测一个函数调用的字节代码,然后插入一个互相调用,然后互相调用互相调用,以添加自定义堆栈。

Well, you can use something like it exists in C with Microsoft C++ compiler :
a specific function (i don't remember the name) which is called automatically on each start and end function.

Also, you count the number of calls and subcalls by increment and decrement the global counter after the start function and before the end function.

For example, with Microsoft .NET , you can insert some function call to increment and decrement your global counter on each call. It's JIT designed.

You can also use a nosql database in order to store your calls.

Also, there is an another thing : use a log system that automatically trace your calls.

Also, when your call stack is full, sometimes it is caused by a recursive function. With a few lines of code and an object, you can store some propagation on each function on each call.
That solution can be also used for detect in any function a special thing : "who is calling me ?"

Also, since Java is a byte-code generated, you can detect the byte-code of a function call and insert before one another function call and after one another function call in order to add your custom stack.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文