java堆、栈、常量池

时间:2021-11-18 10:13:28

java堆、栈

突然在网上看到一篇关于java堆栈共享问题帖子,所以回忆一下java堆栈。首先看看那个帖子
java堆、栈、常量池
首先做一下解答,堆是所有线程共享的内存区域,栈是每个线程独享的,所以那篇博文肯定是错误的。
其次呢博文的这句话也是错误的

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用

java基本数据类型存放在哪?它存放在堆或栈中,具体情况由上下文决定。当这个变量为局部变量的时候,存放在栈中,因为其数据大小与生存期是确定的,而且在栈中的存取速度比堆要快,当这个变量为成员变量是,它肯定是存放在堆中,他是所有线程共享的。
下面回忆一下java堆和栈的区别:
Java堆是和Java应用程序关系最密切的内存空间,所有线程共享Java堆,并且Java堆完全是自动化管理,通过垃圾收集机制,垃圾对象会自动清理,不需自己去释放,堆内存用来存放由new创建的对象和数组。
java栈存取速度比堆要快,不是先线程共享的,据说仅次于位于CPU中的寄存器,在函数中定义的一些基本类型的成员变量和对象的引用变量都在函数的栈内存中分配。
大家可以去JVM的运行机制这边博文中详细了解。

常量池

在这个帖子下面有一个这样的回答
java堆、栈、常量池
现在在回忆一下java常量池
常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。

静态常量池

即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。

运行时常量池

则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。
最简单的一个例子

        Integer a = 120;
Integer b = 120;
System.out.println(a==b);//输出true
Integer c = 390;
Integer d = 390;
System.out.println(c==d);//输出false

java中基本类型的包装类Byte,Short,Integer,Long,Character,Boolean实现了常量池技术,他们默认创建了数值[-128,127]的相应类型的缓存数据,存放在常量池中,所以a和b都是对常量池中120的引用,而c、d超出常量池的范围,他们分别在堆中创建了一块新的空间,c、d的引用地址是不一样的,输出false。
注意Float和Double是没有常量池技术的。
推荐一篇文章Java常量池理解与总结