Java内存的堆栈与常量池

Posted

tags:

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

1.名词解释

:由JVM分配区域,用于保存线程执行的动作和数据引用。栈是一个运行的单位,Java中一个线程就会相应有一个线程栈与之对应。

:由JVM分配的,用于存储对象等数据的区域。

常量池:在编译的阶段,在堆中分配出来的一块存储区域,用于存储显式的String,float或者integer.例如String str="abc"; abc这个字符串是显式声明,所以存储在常量池。

2.看这个例子,用JDK5+junit4.5写的例子,完全通过测试

import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import org.junit.Test;

public class StringTest{

    @Test
    public void testTheSameReference1(){
        String str1="abc";
        String str2="abc";
        String str3="ab"+"c";
        String str4=new String(str2);
        
        //str1和str2引用自常量池里的同一个string对象
        assertSame(str1,str2);
        //str3通过编译优化,与str1引用自同一个对象
        assertSame(str1,str3);
        //str4因为是在堆中重新分配的另一个对象,所以它的引用与str1不同
        assertNotSame(str1,str4);
    }
    

}

      • 第一个断言很好理解,因为在编译的时候,"abc"被存储在常量池中,str1和str2的引用都是指向常量池中的"abc"。所以str1和str2引用是相同的。
      • 第二个断言是由于编译器做了优化,编译器会先把字符串拼接,再在常量池中查找这个字符串是否存在,如果存在,则让变量直接引用该字符串。所以str1和str3引用也是相同的。
      • str4的对象不是显式赋值的,编译器会在堆中重新分配一个区域来存储它的对象数据。所以str1和str4的引用是不一样的。

         

技术分享























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

Java内存分配之堆栈和常量池(转)

JAVA中堆栈和内存分配原理

JAVA中堆栈和内存分配详解(摘抄)

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

面试干货5——请详细说说JVM内存结构(堆栈常量池)

Java堆栈详解