http://clarkht.iteye.com/blog/482644
String oldStr = "hello,clark";
String newStr = oldStr.subString(0,4);
对于这个写法,实际上对于oldStr是一个char[]数组[h,e,l,l,0,,,c,l,a,r,k],对于subString操作,newStr并不是自己copy oldStr的char[]数组hello自己去创建一个新的char[]数组,而是java在背后进行了String Reusing Optimization,它不会自己创建一个新的char数组,而是reuse原来的char数组。所以了,这样就不会有很多的原来的char[]数组的碎片。引用http://www.javablogging.com/string-and-memory-leaks/ 上的列子:
Java代码
public static void sendEmail(String emailUrl) {
String email = emailUrl.substring(7); // 'mailto:' prefix has 7 letters
String userName = email.substring(0, email.indexOf("@"));
String domainName = email.substring(email.indexOf("@"));
}
public static void main(String[] args) {
sendEmail("mailto:user_name@domain_name.com");
}
但是这个虽然在一般情况是好,不过也是有代价的。根据http://nflath.com/2009/07/the-dangers-of-stringsubstring/上,因为字符串不是自己新建一个char[]数组,而是引用了原来的char[]数组,这样oldStr就无法garbage collected ,因为newStr还是拥有oldStr的char[]数组的引用。这样容易引起Outof Memory 异常。解决办法是了,便是让newStr拥有自己的char[]数组,也就是自己在subString时强迫创建自己的char[]数组,这样就不会有garbage collected 的问题(reachable but unused!) 怎么办:
Java代码
String sub = new String( oldString.substring(0, 4) );
---------------------------------------------------------------
为了避免内存拷贝、加快速度,Sun JDK直接复用了原String对象的char[],偏移量和长度来标识不同的字符串内容。也就是说,subString出的来String小对象仍然会指向原String大对象的char[],split也是同样的情况 。这就解释了,为什么HashMap中String对象的char[]都那么大。
-------------------------------------------------------
可以参考:
http://jarfield.iteye.com/blog/583946
分享到:
相关推荐
### 理解Java中的字符串内存分配 #### 概述 在Java中,字符串是一种非常重要的数据类型,广泛应用于各种程序开发场景之中。对于开发者来说,深入理解字符串的内存分配机制不仅能帮助他们写出更高效的代码,还能...
总的来说,"java朗读中文字符串.zip"中的示例可能涵盖了以上这些知识点,通过阅读和学习这些代码,你可以了解如何在Java环境中实现中文文本的语音合成。对于学习和开发涉及语音交互的Java应用,这是一个非常实用的...
在Java编程语言中,字符串(String)是一个特殊的数据类型,其内存位置的理解对于深入理解JVM(Java虚拟机)的工作原理至关重要。本文将详细探讨Java中字符串在内存中的存储位置,并通过实例进行验证。 首先,我们...
在C/C++中,我们需要使用JNI的`GetStringChars`或`GetByteArrayElements`获取Java字符串的字节表示。由于Java字符串是UTF-16编码,因此,处理中文字符时,我们通常需要以宽字符(wchar_t)形式处理,或者先解码为...
在Java编程中,提取文件中的特定字符串是一项常见的任务,尤其在进行日志分析、代码审查或者数据挖掘时。本文将详细讲解如何通过Java的IO流技术来实现这一目标,特别是针对Java源代码文件(.java)的情况。 首先,...
本文将深入探讨Java字符串内存分配的机制,以便更好地理解它们在程序运行时的行为。 首先,我们要明确Java中的字符串有两种主要的创建方式:直接赋值和使用`new`关键字。例如: 1. `String a = "123";` 2. `String...
在Java开发过程中,经常会遇到内存泄漏的问题,尤其是在长时间运行的应用程序中更为常见。本文将详细介绍如何解决Java内存泄漏问题,帮助开发者更好地理解和应对这一挑战。 #### 二、Java内存模型与内存区域 Java...
### Java连接数据库字符串详解 #### 一、JDBC概述与加载驱动 在Java开发中,JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类...
6. **释放资源**:在完成朗读任务后,记得释放`Voice`对象,以防止内存泄漏。这可以通过调用`voice.shutdown()`来完成。 除了基础的文本转语音功能,Freetts还提供了许多高级特性,例如支持多种语言(如英语、法语...
在JNI中,使用`NewStringUTF()`创建的字符串和`GetStringUTFChars()`返回的字节数组,需要在使用后手动释放,避免内存泄漏。使用`DeleteLocalRef()`来释放本地引用。 3. **JNI中的字符串操作**: - JNI中的字符串...
4. **非显式的内存泄露**:除了显式地保留对对象的引用外,还有一些不太直观的情况也会导致内存泄露,比如日志类中对字符串的不当处理。 #### 示例分析 1. **循环添加对象至集合**: ```java Vector v = new ...
JAVA 内存溢出问题是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用的内存大于虚拟机能提供的最大内存。内存溢出问题可以从容器和程序类两个方面进行排查,容器问题可以调整容器参数来解决...
在开发过程中,结合字符串哈希Key算法和内存监控类,可以优化程序性能,防止因内存问题导致的程序崩溃,同时也能提升程序的可维护性和稳定性。然而,设计和实现这样的工具需要考虑各种因素,例如哈希冲突的解决、...
`HeapOfFishStrings.java`可能是一个示例,用来演示字符串对象如何影响内存,因为Java中的字符串是不可变的,所以对字符串的处理特别需要注意,避免不必要的内存占用。 `FishIcon.java`可能是用于展示内存管理概念...
Java编程语言将内存划分为两种...总的来说,理解Java中的堆和栈内存分配机制对于优化代码性能和避免内存泄漏至关重要。开发者需要根据实际需求合理地使用栈和堆,平衡性能和内存消耗,以实现更高效、更稳定的程序运行。
### Java字符串的10个入门知识详解 #### 一、基本数据类型与字符串之间的转换 在Java编程中,经常需要进行基本数据类型与字符串之间的相互转换。这些转换可以通过多种方式进行。 1. **基本数据类型转字符串** - ...
例如,Valgrind是一个内存检测工具,可以帮助我们发现字符串操作中的内存泄漏或越界访问。GDB是另一个强大的调试器,可以让我们逐行检查代码执行,观察字符串变量的变化。除此之外,代码分析工具如SonarQube可以检测...
Java 内存分配是理解Java程序性能和...理解Java内存分配对于编写高效、无内存泄漏的代码至关重要,同时也对诊断和解决性能问题有着深远的影响。通过深入了解这些概念,开发者能够更好地设计和优化他们的Java应用程序。
理解字符串的内存管理对于避免内存泄漏和提高程序性能至关重要。 5. **字符串常量与变量**:字符串可以是常量(不可改变)或变量(可改变)。在C/C++中,字符串常量是字符数组的别名,而Java和Python则有特殊的字符...