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.栈的英文 ...
随机推荐
- 几行命令用minikube快速搭建可测试的kubernetes单节点环境
几行命令用minikube快速搭建可测试的kubernetes单节点环境 需要docker环境,https://www.cnblogs.com/xiaofei12/p/17544579.html,网速 ...
- Chrome 插件 V3 版本 Manifest.json 中的内容脚本(Content Scripts)解析
内容脚本(Content Scripts) 指定在用户打开某些网页时要使用的 JavaScript 或 CSS 文件. 内容脚本是在网页环境中运行的文件.通过使用标准文档对象模型 (DOM),开发者能 ...
- C语言:计算长方形面积问题
#include <stdio.h> #include <stdlib.h> /* run this program using the console pauser or a ...
- java学习之旅(day.15)
IO框架 I:input O:output 流:内存与存储设备间传输数据的通道 数据借助流进行传输 流的分类 按流向分: 输入流:将存储设备中的内容读入到内存中(程序运行) 输出流:将内存中的内容写入 ...
- Python:Python中的参数屏蔽
我们有时会不经意间写下如下代码: def update_indices(indices): indices = [] # 像在更新indices前先将其置空 for i in range(10): i ...
- docker --link容器互联
目录 一.系统环境 二.docker容器互联概述 2.1 docker容器互联的三种方式 2.2 docker --link使用注意事项 2.3 docker --link原理 三.docker容器互 ...
- Java的深浅拷贝认识
目录 浅拷贝 深拷贝 分辨代码里的深浅拷贝 在Java中,深拷贝和浅拷贝是对象复制的两种方式,主要区别在于对对象内部的引用类型的处理上. 浅拷贝 定义: 浅拷贝是指创建一个新的对象,但这个新对象的属性 ...
- win10 使用idea 构建一个ssm的模板maven项目
一.创建一个maven项目 1.1建立一个module作为web项目 File->New->project 选择maven,默认jdk,下面的列表什么都不选,next->输入 ...
- Swoole 源码分析之 Coroutine 协程模块
首发原文链接:Swoole 源码分析之 Coroutine 协程模块 大家好,我是码农先森. 引言 协程又称轻量级线程,但与线程不同的是:协程是用户级线程,不需要操作系统参与.由用户显式控制,可以在需 ...
- c# - 如何在圆角 WPF 窗体中创建圆角矩形?
我正在 WPF 中创建一个应用程序,我想要圆角.收到.现在窗体是无边框的,我正在尝试创建一个圆角矩形并将其放在顶部,使其看起来像 Windows 应用程序的顶部栏. 我做不到. 这是我的代码: < ...