String str1="abc"; 内存分布问题

C++ 知识补充 向量(vector)是一个封装了动态大小数组的顺序容器(SequenceContainer)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。C++中map提供的是一种键值对容器,里面的数据都是成对出现的,如下图:每一对中的第一个值称之为关键字(key),每个关键字只能在map中出现一次;第二个称之为该关键字的对应值。 阅读详情
[Csharp] view plain copy
  1. String str1="abc";  
  2. String str2=new String("abc");  
  3. 有啥区别  

今天在某JAVA群里有人问到这个问题,发觉自己也没搞明白,google一阵找到一篇说的比较明白的文章。

=================================================================

Java把内存划分成两种:一种是栈内存,一种是堆内存。   
    
   在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。   
    
   当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。   
    
   堆内存用来存放由new创建的对象和数组。   
    
   在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。   
    
   在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。   
    
   引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。
   
    

具体的说:
栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
           Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
          栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
          栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。

            比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的。

String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一次生成一个。
        因此用第二种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
        另一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。
======================================================
练习题:
   以下code生成几个String对象
   String a="abc";
   String b="abc";
   String c=new String("abc");
   String d=c.intern();

   String a="abc";                                   yes
   String b="abc";                                    no
   String c=new String("abc");                    yes
   String d=c.intern();                                这句是关键!!

     String c=new String("abc");                  
     String d=c.intern();              
     如果仅仅是这样
     c == d   ? 结果是 false;
     因为引用变量c指向堆内存的地址;但是intern(); 却在栈中开辟了一块内存。
    
     对于本题来讲:
     c.intern(); 执行时,在栈内存中发现存在对象“abc”,所以直接将指针指向“abc”
     这样 a == d, b==d 结果为true;

     所以这条的答案是2
接入 deepseek 实现AI智能问诊 必须包含user角色,用于传递用户输入。system角色可选,用于设置对话背景。多轮对话需要将历史记录添加到messages中。 阅读详情

相关推荐

ECU-TEST笔记&使用技巧01

说明 1)所述均基于如下环境:ECU-TEST 8.0、Win10系统、NI Veristand 2018(HIL测试)。不排除因为版本及软件环境问题,所述方法不奏效或有更好的方法,欢迎交流,一起提高。 2)本博客以问答形式进行,所述问题均来自于实际测试(包括MIL、HIL测试)遇到的问题及需求,目的是提高测试效率和自动化测试序列的可维护性。 3)本博客尽量从测试方法及ECU-TEST原...

Eigrl的博客 1万+

JAVA中Stack和Heap的区别(详解)

1.Java中对象都是分配在heap(堆)中。从heap中分配内存所消耗的时间远远大于从stack产生存储空间所需的时间。 (1)每个应用程序运行时,都有属于自己的一段内存空间,用于存放临时变量、参数传递、函数调用时的PC值的保存。这叫stack。 (2)所有的应用可以从一个系统共用的空间中申请供自己使用的内存,这个共用的空间叫heap。 (3)stack中的对象或变量只要定义好就可使用了,应用程序结束时会自动释放。 (4)而要使用heap中申请的变量或对象只能定义变量指针,并要求在运行过程中通...

qq_47759220的博客 1987

注册“Oracle Provider for OLE DB”和创建链接服务器

注册“Oracle Provider for OLE DB”和创建链接服务器 在sql server 数据库上创建链接服务器,连接oracle数据库,访问接口需要设置为:“Oracle Provider for OLE DB”。 如果电脑上没有这个驱动,安装一个完整的Oracle11gR2程序是一个有效的方法,但这个64位版本的安装包有2个多G, 相当庞大,如果仅仅...

weixin_30760895的博客 2384

String str1 = “abc“; String str2 = “ab“; String str3 = str2 + “c“; str1==str3是false吗?原因?

摘要:在Java中,String str1="abc"与String str3=str2+"c"比较时结果为false。这是因为后者涉及变量拼接,实际会通过StringBuilder创建新对象,导致str3指向不同内存地址。常量字符串相加会被编译器优化,而变量相加则不会。本文解释了Java字符串的内存机制差异,并声明仅供学习交流。

重装系统软件安装卸载新机开荒 215

MOLDFLOW 2012模流分析基础到实战视频教程

├ 1第一讲MF软件安装与界面定制及模流前期准备工作及分析流程介绍 ├ 2第二讲MF建模工具条命令讲解与图层的运用 ├ 3第三讲MF网格类型与适应范围及网格划分、诊断、修复与统计 ├ 4第四讲MF中CAD doctor 模块对导入模型的修复方法与实例 ├ 5第五讲MF中常见各种流道浇口及水路的建模方法与外部导入方法上 ├ 6第六讲MF产品模型导入CAD DOCTOR与修复 ├ 7第七讲MF分析序列设定与网格的划分与诊断及修复 ├ 8第八讲MF材料选择与成型工艺参数设定 ├ 9第九讲MF创建浇注系统:主流道、

QQ_1987083845的博客 2545

Cadence OrCAD: 层次化设计 Hierarchical Design

详细介绍OrCAD的原理图层次化设计方法。

Fantasy237的博客 1万+

String str1="abc";和String str2=new String("abc");的区别

Java把内存划分成两种:一种是栈内存,一种是堆内存。 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 m! _: \7 w2 o" V- v 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。 堆内存用来存放由new创建的对象和数组

Stand1210的博客 2045

应用处理器(AP)、系统级芯片(SoC)与微控制器(MCU)的区别与联系

应用处理器(AP)、系统级芯片(SoC)与微控制器(MCU)的区别与联系

a_zxswer的博客 1694

Java之String类与StringBuffer类

一、String类 1.实例化方式 1)直接赋值法 String str="abc"; String类的设计采用了共享设计模式。在JVM底层实际上会自动维护一个对象池(字符串对象池),如果采用直接赋值法赋值,JVM会先在对象池中查找,如果有,则直接引用;如果没有,则将该实例化对象放到对象池中。 所谓对象池就是一个对象数组。优点:减少内存的开销。 2)构造法 String st...

smell201611010513的博客 1808

【大模型】DeepSeek 高级提示词技巧使用详解

DeepSeek 高级提示词技巧使用详解

congge 1万+

[Dify实战] [安全合规] 用 Dify 优化安全巡检:从经验驱动到标准闭环-带绑定资源

摘要:企业信息系统安全管理中,安全合规巡检面临标准不统一、整改难追踪等痛点。本文提出基于Dify工具的智能化解决方案,通过自动化工作流实现标准检查清单生成、风险等级标注、整改建议输出及审计记录归档。方案采用结构化Prompt模板和Markdown输出格式,涵盖账号权限、数据安全等核心维度,并提供证据收集建议和闭环管理机制,帮助组织从人工经验驱动转向数据流程驱动的合规管理。配套可导入Dify的工作流文件将随后发布。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 272

java中string的内存分布_java中String str1=“abc”内存分配问题?

回答问题1:“常量池”不是在方法区吗?为什么会在堆里?准确地说,"java 常量池不在堆中也不在栈中,是独立的内存空间管理"。对于常量池的解释如下。常量池:"常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池...

weixin_42294133的博客 716

DICOM图像知识:深入详解DICOM的层级关系

解析DICOM的四个主要层级:Patient(患者)、Study(检查)、Series(序列)和SOP(服务-对象对),探讨它们之间的关系、各自的唯一标识符以及在实际应用中的用途

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 3305

面试官:String str = new String(“abc“) 创建了几个对象?

后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,:可能创建 0 或 1 个对象(仅在常量池不存在时创建),且所有字面量相同的引用都指向常量池中同一个对象,此时,堆中新创建的对象在没有其他引用的情况下,稍后会被 GC 回收。将不会触发新的创建,而只是指向池中已存在的对象。,并将参数字符串的字符数组拷贝(或引用,具体实现有优化)过去。:必然在堆上创建新对象(1个),且与常量池中的对象是。

犬小哈 1014

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

经典String str = new String("abc")内存分配问题

Java把内存划分成两种:一种是栈内存,一种是堆内存。            在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。            当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。            堆内存用来存放由new

u011507992的专栏 518

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Java字符串常量池深度解析:内存分布、JDK演进与实战调优

字符串常量池是Java中管理字符串字面量的核心内存机制,其本质是堆内受控的哈希表结构,而非独立内存池。它基于开放寻址法实现,哈希计算依赖对象地址而非内容,直接影响==比较语义和intern()行为。从JDK6永久代到JDK7+堆内存的迁移,彻底改变了GC策略与OOM排查逻辑;而字符串去重(String Deduplication)和分片(Sharding)等现代优化,则进一步提升高并发场景下的稳定性与性能。理解其在JVM内存模型中的真实位置、扩容阻塞特性及与G1/ZGC的协同机制,对解决线上内存泄漏、JSO

weixin_30374009的博客 542

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

JB1-2-基础启航

注释,输出语句,变量,数据类型,字符串,正则,API,运行时数据区,运算符,选择结构,循环结构,流程控制,数组(内存,遍历,拷贝)等。

周航宇的博客 2250

C++笔记(初阶)

C++学习笔记!

hi_ro_a的博客 554

5.C++的内存管理【由浅入深-C++】

本文介绍C和C++的内存管理相关内容。

插花弄玉的博客 1242

leetcode -- 2026.6.30(6.26-6.30共10题)

数据结构出现题目核心考点你掌握的程度数组1, 4, 9双指针、哈希表优化、二分查找、中位数✅ 已拿下链表2虚拟头结点、进位处理、逆序加法✅ 已拿下字符串滑动窗口、中心扩展、Z字形模拟、状态机、递归/DP⚠️ 10需重点巩固数学/数字7, 9溢出判断、反转一半、回文判断(不转字符串)✅ 已拿下。

qq_59463944的博客 207

Python高级核心:对象模型、引用计数与描述符协议深度解析

Python高级编程的本质,不在于语法糖的堆砌,而在于理解其底层运行机制——对象模型定义了属性查找链与内存布局,引用计数与GC协同机制决定了内存释放时机与循环引用风险,描述符协议则支撑着@property、@classmethod等关键特性的行为逻辑。掌握这三者,才能真正诊断性能瓶颈、规避生产级内存泄漏、写出线程安全且可复用的工业级代码。本文聚焦CPython解释器层的真实约束与设计契约,结合金融风控、AI推理等高可靠性场景,详解对象生命周期管理、描述符优先级规则、弱引用安全替代方案等硬核实践,帮助Pyth

weixin_33690367的博客 505

java堆栈string str1 = "abc";_String str1 = “abc”,“abc”分配在内存

1,寄存器:存取数据最快的地方,不能直接控制2,堆栈(又叫栈stack)位于RAM(随机访问存储器)中,通过堆栈指针上下移动来实现存取数据,堆栈指针向下移动,则分配新的内存,堆栈指针向上移动,则释放内存,堆栈的优势是,存取速度要比堆块,仅次于位于CPU中的寄存器,但是java系统必须知道存储在堆栈内所有项目的确切生命周期,以便上下移动指针。<1>Java的基本数据类型共有8种,即int...

weixin_39958559的博客 336
上一篇: eclipse中创建maven项目并发布(包括tomcat配置)
下一篇: jsp/js读取properties文件的方法
阳小良
博客等级 码龄17年 54粉丝 155原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值