Java中的栈、堆和常量池
Java程序是运行在JVM(Java虚拟机)上的,因此Java的内存分配是在JVM中进行的,JVM是内存分配的基础和前提。
Java程序的运行会涉及以下的内存区域:
寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中。
堆:存放new出来的对象,注意创建出来的对象只包含各自的成员变量,不包括成员方法。
常量池:存放常量,如基本类型的包装类(Integer、Short)和String,注意常量池位于堆中。
代码段:用来存放从硬盘上读取的源程序代码。
静态域:用来存放static修饰的静态成员。
下图表示了程序大致的内存分配情况:

1、声明和实例化
声明:A a = null; 声明一个A类的对象a,a放在栈中。
实例化:a = new A(); 实例化这个对象a,new A() 放在堆中。
String s = newString("a"); 创建了两个对象,一个是在常量池中,一个是在堆内存中,常量池的为"a",堆内存中为new String()。变量s指向该new string()对象,而该对象又指向在常量池中的字符串常量”a”。注意的是,在new的时候java虚拟机先去内存的常量池中查找”a”这个对象,如果有就不创建了,直接把堆中的对象指向该字符串。
String s = "a"; 的意思就是在栈中创建一个字符串类型的变量s,并且变量s直接指向常量池中的字符串对象”a”,省去了中间的堆内存中的对象。注意的是,String s = "a",这行代码被执行的时候,java虚拟机首先在字符串池中查找是否已经存在了值为"a"这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。
2、数据存放形式
String s1 = "china";
String s2 = "china";
String s3 = "england";
String s4 = new String("china");
String s5 = new String("england");

对于字符串,其对象的引用(这里指:s1,s2,s3,s4,s5)都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期new出来的(一旦new就会开辟新的堆内存)才存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
3、数据存放位置
int s1=6; //s1存放在栈中;6存放在常量池
char s2 = 'g'; //s2存放在栈中;'g'存放在常量池
boolean flag = true; //flag存放在栈中;true存放在常量池
byte b = 6; //b存放在栈中;6存放在常量池
String s3 = "china"; //s3存放在栈中;"china"存放在常量池
String s4= new String("abc"); //s4存放在栈中;new String()存放在堆中;"abc"存放在常量池中
注意:
栈(stack):主要保存基本类型(或者叫内置类型)(char、byte、short、int、long、float、double、boolean)和对象的引用,数据可以共享,速度仅次于寄存器(register),快于堆。
Java中的栈、堆和常量池的更多相关文章
- java中关于string类和常量池的一点猜想
public class StringTest { /** * @param args */ public static void main(String[] args) { test1 ...
- Java中的栈,堆,方法区和常量池
要说Java中的栈,堆,方法区和常量池就要提到HotSpot,HotSpot是Sun JDK 和 Open JDK中所带的虚拟机. (Sun JDK 和 Open JDK除了注释不同,代码实现基本上是 ...
- java内存管理--栈、堆和常量池
今天有朋友问java中String[] str = s.split(",")的内存分析,于是开始查资料并测试.首先,发现在java的内存管理中"常量池"是个很奇 ...
- 浅谈Java中的栈和堆
人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...
- 如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)
背景 Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题. 有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手-) ...
- Java - String 的字面量、常量池、构造函数和intern()函数
一.内存中的 String 对象 Java 的堆和栈 对于基本数据类型变量和对象的引用,也就是局部变量表属于栈内存: 而通过 new 关键字和 constructor 创建的对象存放在堆内存: 直接的 ...
- Java内存分析--栈--堆
Java内存分析--栈--堆 JVM的内存分析: 1.栈内存 1.连续的存储空间,遵循后进先出的原则. 2.每个线程包含一个栈区,栈区只保存基础数据类型的对象和自定义对象的引用. 3.每个栈中的数据都 ...
- 使用Java中的动态代理实现数据库连接池
2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...
- java中使用Semaphore构建阻塞对象池
java中使用Semaphore构建阻塞对象池 Semaphore是java 5中引入的概念,叫做计数信号量.主要用来控制同时访问某个特定资源的访问数量或者执行某个操作的数量. Semaphore中定 ...
- java中的栈(利用数组实现栈)
java中的栈(利用数组实现栈) 常见的数据结构:https://blog.csdn.net/weixin_43304253/article/details/119764275 栈的介绍 1.栈的英文 ...
随机推荐
- ansible(10)--ansible的systemd模块
1. systemd模块 功能:管理服务启动与停止,与 service 模块用法一致: 主要参数如下: 参数 说明 name 指定需要控制的服务名称 state 指定服务状态,其值可以为stopped ...
- vscode插件安装和配置支持vue3
一.常用插件介绍 1.插件Vue 3 Snippets 作用:用于vue3的智能代码提示,语法高亮.智能感知.Emmet等.替代Vetur插件,Vetur在vue2时期比较流行. 常用命令:vuein ...
- JDK源码阅读-------自学笔记(八)(数组演示冒泡排序和二分查找)
冒泡排序 算法 比较相邻的元素.如果第一个比第二个大,就交换他们两个 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数 针对所有的元素重复以上的步骤,除 ...
- 解析 ABP vNext 依赖注入实现【属性注入】的原理
前言 这几天闲来没事看看ABP vNext的文档和源码,关于关于依赖注入(属性注入)这块儿产生了兴趣. 我们都知道.Volo.ABP 依赖注入容器使用了第三方组件Autofac实现的.有三种注入方式, ...
- pageoffice 5.x升级到pageoffice 6.x的关键步骤
Vue+Springboot前后端分离项目 将后端Springboot项目中pom.xml文件中对于pageoffice的jar引用升级成6.0版本,以maven中央仓库(https://mvnrep ...
- QT中各控件的属性和方法
1.在QT6中,QLabel类具有许多属性和方法,以下是QLabel类的常见属性和调用方法:setText(const QString &text):设置标签的文本内容.setAlignmen ...
- java学习之旅(day.13)
常用类 Object类 object类是所有类的父类,所有类直接或间接继承object类 所有类,如果没书写extends显示继承某个类,都默认继承object类 getClass()方法 返回值是c ...
- Java学习之旅(day.09)
封装 把数据包装起来,给你能看的,不能看的包装起来不让你看 该露的露,该藏的藏 程序设计要求"高内聚,低耦合". 高内聚指类的内部数据操作细节自己完成,不允许外部干涉: 低耦合指仅 ...
- 阿里云sdk调用
slb调用 环境包安装 pip install alibabacloud_credentials --trusted-host mirrors.aliyun.com -i http://mirr ...
- 环境变量管理工具Modules的安装
一.软件依赖tcl软件 (1)tcl下载地址:http://www.tcl-lang.org/software/tcltk/(2)编译安装 cd unix/ ./configure --prefix= ...