当前位置:首页 » 服务存储 » 字符串存储在jvm哪里
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

字符串存储在jvm哪里

发布时间: 2022-11-05 10:40:43

A. java中字符串池存放在内存的哪个区域

字符串首先是一个对象。
举个例子:
String
str0
=
"abc";
String
str1
=
new
String("abc");
当执行String
str0
=”abc”;时,JVM会在栈中创建三个char型的值
’a’
,
’b’

’c’
,然后在堆中创建一个String对象,它的值(value)是刚才在栈中创建的三个char型值组成的数组{
’a’
,
’b’
,
’c’
},最后这个新创建的String对象的值”abc”会被添加到字符串池中。如果我们接着执行String
str1=new
String(”abc”);代码,由于”abc”已经被创建并保存于字符串池中,因此JVM只会在堆中新创建一个String对象,但是它的值(value)是共享前一行代码执行时在字符串池中的

abc

;

B. Java:字符串在JVM常量池中是如何存储的呢

首先你要知道jvm常量池也是对象池,它和在堆中的存储没有区别(底层存储都是一样的,只是对象之间的引用有差别)。那为什么要有常量池呢?因为它可以节省时间和空间,当需要一个对象的时候,可以直接从常量池中获取,而不需要重新创建,这样也就节省了时间和空间(常量池判断对象是否存在应该是equals方法)。
除了String外,Java的8种基本类型(Byte, Short, Integer, Long, Character, Boolean, Float, Double)除Float和Double以外,其它六种都实现了常量池。
楼主这么好学,我出个题目给楼主:
Integer i = 127;
Integer j = 127;
System.out.println(i == j);
提示:对象存在常量池

Integer m = 128;
Integer n = 128;
System.out.println(m == n);
提示:对象存在堆内存

C. java中字符串常量放在哪里

str1和str2分别
创建两个对象 Hello对象和str引用对象
两个必须存放在堆中
str指向堆中的Hello对象
也就是说 两个对象和str的地址全部存放在堆中

String str="abc"; * 引用数据类型肯定存放在堆中 栈中放置的是参数变量而不能放对象 对象只能放在堆中

它只创建一个对象 在堆中创建一个对String类的对象引用变量str(引用变量肯定是存放在堆里的),然后查找栈中是否有"abc",若没有则将"abc"存放进栈,并令str指向"abc",若已经存在则直接令str指向"abc".(也就是说引用变量本身只能存放在堆中 它的值是所指向的字符串abc 它的地址存放在栈中) 它创建多个"abc"字符串在内存中其实只存在一个对象而已,这样有利于节省内存空间同时在一定程度上提高程序运行速度

String str=new String("abc");* 所以通过new操作符的操作都是在堆完成的

它创建两个对象 abc对象和str引用对象 两个必须存放在堆中 str指向堆中的abc对象 也就是说 两个对象和str的地址全部存放在堆中 因为使用了new操作符 所以下面的例子里str2,str3和str4即使是值都为abc因为str2的地址在栈中 str3和str4的地址各自开辟空间 所以他们的地址肯定不一样了
但是它们的值是一样的 那就是abc

String str2 = "abc";
String str3=new String ("abc");
String str4 =new String ("abc");

equals:equals就是比较值 ==在基本类型里也是比较值 在引用类型里是比较地址 注意这个区别就OK了!

表示堆中的引用变量的值是否相同(引用类型变量比较的是他们本身的值,本身的值是通过引用变量地址指向的对象或字符串来得到的,不管这个被指向的字符串或者对象是在栈中还是堆中)
==:表示堆中或者栈中的基本类型的值或者引用变量的地址是否相同(基本类型比较的是他们本身的值,引用类型变量比较的是地址)

当equals为true时,==不一定为true;

D. java中声明一个字符串变量分别放在内存的哪些地方 比如说String a = "abc"

"abc"是分配在栈中的。

而a只是一个对象,一个指向存放"abc”栈的对象,分配在堆中。

许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“abc”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。
这个语句声明的是一个指向对象的引用,名为“a”,可以指向类型为String的任何对象,目前指向"abc"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:
String string = a;
我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。

E. java中String类型存储位置

一、new String都是在堆上创建字符串对象。
当调用 intern() 方法时,
编译器会将字符串添加到常量池中(stringTable维护),
并返回指向该常量的引用。

二、通过字面量赋值创建字符串(如:String str=”twm”)时,
会先在常量池中查找是否存在相同的字符串,若存在,
则将栈中的引用直接指向该字符串;若不存在,则在常量池中生成一个字符串,
再将栈中的引用指向该字符串。

三、常量字符串的“+”操作,
编译阶段直接会合成为一个字符串。
如string str=”JA”+”VA”,
在编译阶段会直接合并成语句String str=”JAVA”,
于是会去常量池中查找是否存在”JAVA”,从而进行创建或引用。

四、对于final字段,编译期直接进行了常量替换(而对于非final字段则是在运行期进行赋值处理的)。
final String str1=”ja”;
final String str2=”va”;
String str3=str1+str2;
在编译时,直接替换成了String str3=”ja”+”va”,根据第三条规则,
再次替换成String str3=”JAVA”

五、常量字符串和变量拼接时(如:String str3=baseStr + “01”;)
会调用stringBuilder.append()在堆上创建新的对象。

六、JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,
如果存在,则返回常量池中的引用,这一点与之前没有区别,
区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,
而只是在常量池中生成一个对原字符串的引用。简单的说,就是往常量池放的东西变了
原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。

举例说明:

String str2 = new String(“str”)+new String(“01”);
str2.intern();
String str1 = “str01”;
System.out.println(str2==str1);

在JDK 1.7下,当执行str2.intern();时,
因为常量池中没有“str01”这个字符串,所以会在常量池中生成一个对堆中的“str01”的引用
(注意这里是引用 ,就是这个区别于JDK 1.6的地方。在JDK1.6下是生成原字符串的拷贝),
而在进行String str1 = “str01”;字面量赋值的时候,常量池中已经存在一个引用,
所以直接返回了该引用,因此str1和str2都指向堆中的同一个字符串,返回true。

String str2 = new String(“str”)+new String(“01”);
String str1 = “str01”;
str2.intern();
System.out.println(str2==str1);

将中间两行调换位置以后,因为在进行字面量赋值(String str1 = “str01″)的时候,
常量池中不存在,所以str1指向的常量池中的位置,而str2指向的是堆中的对象,
再进行intern方法时,对str1和str2已经没有影响了,所以返回false。

F. java中的String常量是存放在栈中还是堆中

string 字符串是经过final修饰的,在源码中就可以看到,所以string str= “123”声明的变量str是在栈区存放的,但声明变量的值‘123’是在常量池中存放的,如果是经过 new
String str = new String(123);这样的,变量名str是在堆区存放的,但‘123’还是在常量池中存在,在常量池中存放时会先看常量池中有没有这个‘123’值,有的话就把这个值的地址值赋给堆区中的str,没有就新建一个;

G. java中,字符串,如何存储在内存中的哪个区域

字符串在java中是不可变序列,每一个双引号的字符串序列都是常量,存在常量池中。但String类型的对象,属于对象范畴,按对象的特性存储。

H. java字符串常量存放在内存meta space stack native heap pearmgen哪个区域

metaspace:JDK 8的HotSpot JVM现在使用的是本地内存来表示类的元数据,这个区域就叫做元空间。
heap:堆内存用于存放由new创建的对象和数组。
stack:在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。
pearmgen:移除永久代(Permanent Generation (PermGen)),从JDK
7开始Oracle就开始行动了,比如:本地化的String从JDK 7开始就被移除了永久代(Permanent Generation )。JDK
8让它最终退役了。替换者就是元空间。
字符串常量,应该是存放在堆中的。

I. java中字符串池是存在于栈中还是存在于堆中

1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
3. Java中的数据类型有两种。
一种是基本类型(primitive types)出于追求速度的原因,就存在于栈中。
出于追求速度的原因,就存在于栈中。
另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。
4. String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。

值得注意的是,一般String类中字符串值都是直接存值的。但像String str = "abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!

用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享

使用String str = "abc";的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。

J. java中的String常量是存放在栈中还是堆中

系统内存一般情况来说分为四个
heap 堆 放 对象 也就是new 出来的东西
stack 栈 放局部变量
static segment 静态区 用来放 静态变量 和字符串常量
data segement 代码区 用来放代码的

如果 一个字符串是 String s = "abc";它放在栈里
如果一个字符串 用创建对象的方式 String s = new String("abc");
那它是放在了 堆里 而如果单纯的 一个 "abc" 这个输入字符串常量 是放在static segement里