如果匿名对象使用外部方法 `infinity` 的局部变量,会导致堆栈溢出吗?

huangapple go评论63阅读模式
英文:

If anonymous object use the local variable of external method infinity, it can be stack overflow or not?

问题

以下是你提供的内容的翻译:

关于 Java 中的匿名对象,我有一个问题。

如果我创建一个静态方法(name = go()),该方法拥有一个匿名对象,并且这个匿名对象使用了 go() 方法的局部变量。

我知道,用于匿名对象的局部变量必须声明为 final

然后,final 变量(numberCnt)在堆栈区域创建,而不是在堆区域。

堆栈区域不是垃圾回收的目标。

如果我无限地调用 go(),是否会导致堆栈溢出错误?

以下是我的问题来源。

package com;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestMain {
    public static void main(String[] args) {

        int i = 0;

        while (true) {
            i++;
            go(i);
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }

            if (i > 10_000_000) {
                i = 0;
            }
        }
    }

    private static void go(int i) {

        int numberCnt = i;

        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                String rtnValue = "Number=>" + numberCnt;

                System.out.println("Number=>" + rtnValue);

                return rtnValue;
            };
        };

        ExecutorService executorService = Executors.newFixedThreadPool(4);

        executorService.submit(callable);
    }
}
英文:

I have a question about anonymous object in Java.

If I make a static method(name = go()) which has one anonymous object and this anonymous object uses the local variable of go().

I know that local variable which is used for anonymous object has to be declared to be final.

And then final variable(numberCnt) is made in stack area instead of heap area.

The stack area is not target of GC.

if I call go() infinitely, will stack overflow occur or not?

The below is my question source.

package com;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestMain {
	public static void main(String[] args) {

		int i =0;

		while(true) {
			i++;
			go(i);
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
			}

			if(i &gt; 10_000_000) {
				i=0;
			}
		}
	}

	private static void go(int i) {

		int numberCnt = i;

		Callable&lt;String&gt; callable = new Callable&lt;String&gt;() {
			@Override
			public String call() throws Exception {
				String rtnValue = &quot;Number=&gt;&quot; + numberCnt;

				System.out.println(&quot;Number=&gt;&quot; + rtnValue);

				return rtnValue;
			};
		};

		ExecutorService executorService = Executors.newFixedThreadPool(4);

		executorService.submit(callable);
	}
}

答案1

得分: 2

这个匿名类在创建匿名类对象的时刻复制了它所捕获的变量的值。所以基本上你的匿名类有一个隐藏的 int 实例变量来捕获 numberCnt,你可以想象,在幕后,编译器基本上会将 numberCnt 传递到匿名类的隐藏“构造函数”中,以初始化这个隐藏的实例变量。当函数返回时,go 的栈帧已经消失了,在堆栈上永远不会有超过 1 个 go 的栈帧。你只会在堆上得到许多匿名类的实例,每个实例都有一个不同值的 int 实例变量。

英文:

The anonymous class copies the value of the variables it captures at the moment the anonymous class object is created. So basically your anonymous class has a hidden int instance variable for its capture of numberCnt, and you can imagine, behind the scenes, the compiler basically passes numberCnt into the hidden "constructor" of your anonymous class to initialize this hidden instance variable. The stack frame of go is gone when the function returns, and there is never more than 1 stack frame for go on the stack. You just get lots of instances of your anonymous class on the heap, and each of those instances has an int instance variable with a different value.

huangapple
  • 本文由 发表于 2020年9月14日 00:01:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63872751.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定