Code前端首页关于Code前端联系我们

Java面试题:内存中栈区、栈和方法区的使用

terry 2年前 (2023-09-25) 阅读数 52 #后端开发

问题:解释一下内存使用中栈、栈和方法区的使用。

答:通常我们定义基本数据类型的变量、对象的引用,并将它们存储在函数调用的地方,都是使用JVM中的堆空间;当通过 new 关键字和构造函数创建的对象放置在堆空间上时。堆是垃圾收集器管理的主要区域。由于目前的垃圾收集器都采用分代收集算法,因此堆空间也可以分为新生代和老生代。更具体地说,可以分为Eden、Survivor(也可以分为From Confluence和Survivor)和Tenured;方法区和堆栈是每个线程共享的内存区域,用于存储JVM已经加载的类信息、常量、静态变量、JIT编译器编译的代码等。数据;程序中的字面量如直接写100、“hello”等常量放置在常量池中,它是方法区的一部分。堆栈板运行速度最快,但堆栈很小。通常许多对象被放置在堆栈空间中。堆和堆栈大小可以通过 JVM 启动参数进行配置。当堆栈空间用完时,会发生StackOverflowError,而堆栈和池空间不足时会导致OutOfMemoryError。

String str = new String("hello");

java面试题:内存中栈(stack)、堆(heap)和方法区(method area)的用法

上面的语句中,变量str被放入堆栈,新创建的字符串对象被放入堆栈,文字“hello”被放入方法区。

补充1:在较新版本的Java中(自Java 6更新以来),由于JIT编译器的发展以及“逃逸分析”技术的逐渐成熟,出现了堆上分配、标量替换等优化技术创建必须在堆上分配的 Fact 对象已变得不那么绝对。

补充2:运行时常量池和Class文件的常量池一样,都是动态的。 Java不需要常量,它们只能在编译期间创建。新常量也可以在运行时插入到池中。类 String() 方法的内部如下所示。

看下面的代码执行结果,对比Java 7前后的结果,看看是否一致。

String s1 = new StringBuilder("go")
    .append("od").toString();
System.out.println(s1.intern() == s1);
String s2 = new StringBuilder("ja")
    .append("va").toString();
System.out.println(s2.intern() == s2);

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门