javastring内存
① java中String字符串的存储大小也就是容量是多少呢能存多少字符。
String str="abc...";这样定义的字符串是存在字符串池中的
String str=new String("abc...")这样定义的字符串是在堆内存中的,然后被栈内存的对象str引用
所以字符串是对象,是在内存中存储的,不像基本数据类型有各自的长度,字符串应该是只要是内存不满,是没有长度限制的
② java使用软引用可以回收String的内存吗
如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。
个人认为将String对象软引用没什么大的用处,因为一个String占用内存很少,软引用基本都是用来给那些占用内存大的对象使用的,如Bitmap等
③ java String类 开辟内存问题
首先你要知道String是怎么分配内存的,如果使用字符串直接赋值,比如str="abc",那么它会先去常量区找,如果常量区已经有abc,那就直接把str指向abc,如果没有,它就在常量区再分配一个abc。使用new String("abc")的话,不管常量区有没有,它都会在堆里分配一个新的"abc"。
现在回答你的问题。
第一个问题,JAVA的常量字符串+,编译器会自动优化,str3="ab"+"c",经过编译器优化后,实际上等于str3="abc",而常量区已经有一个str分配的"abc",因此str3直接指向str指向的"abc",因此str==str3。
subString(0,2)返回的也是一个string,它的分配也符合上述的规则,subString(0,2)返回"ab",ab在常量区没有对应的值,因此它会另外开辟内存,所以str2 != str。
第二个问题,subString的工作方式是,如果截取的是整个字符串,那它不会新new一个返回,而是直接返回原字符串。因此str.substring(0,3)实际上返回的就是str,所以它们是相等的。str.substring(0,1)截取的是第一个字符"a",这时候返回的也不是你想象的常量区的字符,而是一个新new出来的地址。
我们可以试试:
String str = "abc";
String str2 = "a";
System.out.println(str.substring(0,1) == str2);
System.out.println(str.substring(0,1).equals(str2));
第一个输出false,第二个输出true。因为虽然前面str2初始化后常量区已经有一个"a",但subString截取的字串是新new出来的,不是直接指向常量区的"a“的。
④ Java中 String字符串内存分配问题
jvm中有个String pool,一般在池中有的对象就不会再去生成一个新的。
String s1 = "abc";
生成了一个字符串对象"abc"并放入pool中,定义了一个String变量s1并指向"abc"。
String s = "abc" + s1 + "def";
等式右边有三个String 对象 "abc" 、s1 、"def"
这里("abc"==s1)是true,就是说是引用的同一个内存地址。
"abc"已经在池中了,直接从池中取出来,这句又创建了一个"def"的String对象并放入池中。
当前二个String对象做连接的时候,又会创建一个新的String对象"abcabc",并放入池中;然后再做字符串相加"abcabc"+def又生成一个字串对象,最后变量s指向这个新的String对象。
所以用+来连接字串会产生很多临时的字串对象,效率低。一般使用StringBuffer或StringBuilder来做字串连接。
可以使用new String()来生成一个新的String对象并单独分配内存空间。
------------------------------------------------------
查了下资料,已经改了回答内容。
String s = "abc";
这句是定义一个String变量s,jvm会先去字符串池中找有没有"abc",有的话就把s指向"abc",没有就会先在池中创建一个,再让s指向"abc"。
String s = new String("abc");
这句是先定义一个String变量s,然后在内存中分配新的空间"abc"再让s指向这个内存地址。
⑤ Java StringBuilder和String的内存分析的问题
它们的实现机制不同,这个和有没有人接收没有关系,concat()返回是一个指向常量池111333的全新对象,没有改变s2的引用。至于replace()方法也有多种实现方式,但据我猜测它的实现就像C中的动态数组一样,总之不管它是怎么实现的,sb2最终就是指向了aaaccc。
再多说一句,这个应该在逻辑上理解,而底层实现多种多样,怎么实现都不可以,无非就是一个效率问题,concate方法意在返回一个连接之后的数组,而非销毁对象S2,append方法是附加的意思,意义不言自明了,
⑥ java string 的内存运算模型,求下面的内存运算,感觉和自己以前了接的有所不一样,求求解。
String这个类比较特殊,他有一个自己的String池。
原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。比如你的 "a"+"b"
原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。比如你的 a+b
就是说 你 a="aabb"; 打印 a=="aabb" 和 a=="aa"+"bb" 为真。打印a== new String("aaaa")为假
String aa="aa";String bb="bb";打印a==aa+bb也为假
⑦ 获取java中String类型对象的内存地址值
String str1 = "abc";String str2 = "abc";System.out.println(str1==str2); //true
这样就是true了
String str="abc";System.out.println(str.getBytes());
这个就是地址[B@7150bd4d B可能是类名 因为我的类是B @后面的大概是地址了 没研究过 但是过去地址确实是这个
⑧ java String 内存地址问题如何获取 String 内存地址!
hashCode()返回的是JVM中地址的哈希码,而不是JVM中的地址,要想得到str在物理内存中的真实地存,那只有用JNI技术调用c/c++去实现,否则无能为力,因为java超不出JVM,而JVM对物理内存地址是“不可见”的,否则java中不就有了指针,而去直接操作内存了,当然这是与java语言相违背的。这些只是我个人见解,说不定还真有高手直接用java语言得到了物理内存中的地址了呢。