java中 关于常量池 栈内存 堆内存

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中 关于常量池 栈内存 堆内存相关的知识,希望对你有一定的参考价值。

String a=“abc”;

int a=1;
上面的a是存放在 栈内存中,然后指向常量池中的abc么?
那么int a=1中的a是不是也是放在栈内存中,指向常量池中的1 啊????

Java中所有局部变量和对象的引用都是存储在栈内存中的,int a = 1;它是局部变量肯定是在栈内存,但是它与常量池没有关系;
常量池是堆内存中的一部分,专门用来存储字符串常量;所以String a="abc"中,引用a是存储在栈内存的,指向常量池中的"abc";

但是如果是String a = new String("abc");就又不一样了,对于通过构造函数得到的"abc"字符串对象,引用a还是在栈内存,但是"abc"不会存到字符串常量池中,而是在常量池之外的其他堆内存中再生成一个"abc",由于这个对象与原先常量池中的"abc"对象是equal关系,它们之间会建立起一种联系;
参考技术A java中空间分为3个,串池、堆、栈、其中串池是放字符串的,比如“1234”,堆是放对象的。栈是放变量的。 参考技术B 常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。
Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和
multianewarray等指令建立,不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事
先告诉编译器,因为是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。

关于java中string的内存位置

java运行时内存分五部分:

  线程共享:堆内存、方法区(包括常量池)

  线程私有:栈内存、本地方法栈、程序计数器

 

string不是基本数据类型,那么一个string的内存位置是什么呢?一共有两种情况:

  1、string直接赋值:

    String s = "haha";

    s的引用存在栈内存中,引用指向的haha存在方法区的常量池中(先判断常量池中是否有一个haha,存在则直接指向)

  2、string对象new创建

    String s = new String("haha");

    s的引用存在于栈内存中,引用指向的haha对象,存在堆内存中(每new一次,在堆中创建一个新的haha对象)

 

总结:

  1、string类型的引用,都是存在栈内存中的;

  2、string引用指向,直接赋值存在栈内存,new出来的存在栈内存。

以上是关于java中 关于常量池 栈内存 堆内存的主要内容,如果未能解决你的问题,请参考以下文章

堆,栈,常量池

关于java中string的内存位置

Java 中的内存分配

js的栈内存和堆内存

Java内存的堆栈与常量池

Eclipse中的快捷键快速生成常用代码(例如无参带参构造,setget方法),以及Java中重要的内存分析(栈堆方法区常量池)