zoukankan      html  css  js  c++  java
  • 解释内存中的栈(stack)、堆(heap)和方法区(method area) 的用法?

    通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的

    现场保存都使用 JVM 中的栈空间;而通过 new 关键字和构造器创建的对象则放在

    堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收

    集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为 Eden、

    Survivor(又可分为 From Survivor 和 To Survivor)、Tenured;方法区和堆都

    是各个线程共享的内存区域,用于存储已经被 JVM 加载的类信息、常量、静态变

    量、JIT 编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的 100、”

    hello”和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来

    最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过 JVM

    的启动参数来进行调整,栈空间用光了会引发 StackOverflowError,而堆和常量

    池空间不足则会引发 OutOfMemoryError。

    String str = new String("hello");

    上面的语句中变量 str 放在栈上,用 new 创建出来的字符串对象放在堆上,而”

    hello”这个字面量是放在方法区的。

    补充 1:较新版本的 Java(从 Java 6 的某个更新开始)中,由于 JIT 编译器的发

    展和”逃逸分析”技术的逐渐成熟,栈上分配、标量替换等优化技术使得对象一

    定分配在堆上这件事情已经变得不那么绝对了。

    补充 2:运行时常量池相当于 Class 文件常量池具有动态性,Java 语言并不要求

    常量一定只有编译期间才能产生,运行期间也可以将新的常量放入池中,String

    类的 intern()方法就是这样的。

    看看下面代码的执行结果是什么并且比较一下 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);

  • 相关阅读:
    自定义View
    Android Parcelable
    java IO
    如何安全退出已调用多个Activity的Application?
    cookie和session
    Excel 使用AutoFill提示“类Range的AutoFill方法无效”
    解决“配置系统未能初始化”问题
    Android控件第7类——对话框
    Android控件第6类——杂项控件
    Android控件第5类——ViewAnimator
  • 原文地址:https://www.cnblogs.com/programb/p/13021296.html
Copyright © 2011-2022 走看看