字符串是软件开发中最为重要的对象之一。通常,字符串对象或者其等价对象,在内存中总是占据了最大的空间块。因此如何高效地处理字符串,必将是提高系统整体性能的关键所在。
String对象及其特点
String对象是Java中重要的数据类型,它不是基础数据类型。在Java中,String对象可以认为是char数组的延伸和进一步封装。下图展示了Java中String类的基本实现,它主要由3部分组成:char数组、偏移量和String的长度。 char数组表示String的内容,它是String对象所表示的字符串的超集。String的真实内容还需要借助偏移量和长度在这个char数组中进行定位和截取。
String对象有3个基本特点:
不变性
不变性是指String对象一旦生成,则不能再对它进行改变。
针对常量池的优化
当两个String对象拥有相同的值时,它们只引用常量池中的同一个拷贝。当同一个字符串反复出现时,这个技术可以大幅度节省内存空间。
类的final定义
作为final类的String对象,在系统中不可能有任何子类,这是对系统安全性的保护。
substring()方法的内存泄露
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this : new String(
offset + beginIndex, endIndex - beginIndex, value);
}
// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
在方法最后,返回了一个新建的String对象。查看该String的构造函数以及函数注释可知,这是一个包作用域的构造函数,其目的是为了高效快速地共享char数组。
但在这种通过偏移量和长度来定位和截取字符串的方法中,String的原生内容value数组被整个复制到新的子字符串中。设想,如果原生字符串很大,截取的字符串长度却很短,那么截取的子字符串中却包含了整个原生字符串的所以内容,并占据了相应的内存空间,而仅仅通过偏移量和长度来定位和截取真实内容。
提高了运算速度,浪费了大量的内存空间。典型的空间换时间!
下面以一个实例来说明内存泄露的情况:
static class HugeString {
private String str = new String(new char[100000]);
public String getSubStr(int beginIndex, int endIndex) {
return str.substring(beginIndex, endIndex);
}
}
static class ImprovedHugeString {
private String str = new String(new char[100000]);
public String getSubStr(int beginIndex, int endIndex) {
return new String(str.substring(beginIndex, endIndex));
}
}
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 1000; i++) {
//HugeString hugeString = new HugeString();
ImprovedHugeString hugeString = new ImprovedHugeString();
list.add(hugeString.getSubStr(0, 5));
}
System.out.println("over");
}
ImprovedHugeString类的实例不会引发内存泄露的原因是因为其重新调用了没有内存泄露风险的构造函数,对需要占用的内存空间进行了重新整理。释放了substring方法返回的、存在内存泄露的String对象的强引用,以便其能被GC回收。如下所示:
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off + size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
分享到:
相关推荐
16. **字符串与字符串类**:String类的常用方法,如concat、substring、indexOf、replace等。 17. **集合框架**:List、Set和Map接口,ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap的使用。 18. **...
1. **Java基础**:介绍Java语言的基本语法,如变量、数据类型、运算符、控制流程(条件语句、循环)、数组、字符串以及异常处理。这些基础知识是理解和编写任何Java程序的基石。 2. **面向对象编程**:深入讲解Java...
10. **Java虚拟机(JVM)**:理解JVM的工作原理,如内存管理(堆、栈、方法区等)、垃圾收集、类加载机制,对于优化Java应用程序性能和排查问题非常有帮助。 由于这份笔记并非针对Java 8,因此可能不包含Java 8的新...
10. **JVM原理**:了解Java虚拟机(JVM)的工作原理,如内存模型、类加载机制、垃圾回收等,有助于优化程序性能和解决内存问题。 11. **Java SE与Java EE**:Java Standard Edition(SE)是基础,Java Enterprise ...
java笔试题重复字符串优化 Go 程序 这是有助于优化 Go 程序的工具和技术的整理。 它分为两部分——工具和技术。 工具查看帮助您检测代码的 go 命令行工具。 技术查看您可能用来获得性能的想法列表。 最后还有一大堆...
随着版本的更新,JDK提供了更多新特性和性能优化,例如,从JDK 1.0到JDK 1.5(即Java 5)引入了泛型、枚举、可变参数列表等特性,显著增强了Java的编程能力和灵活性。 #### 二、Java语言基础详解 深入Java语言基础...
3. **switch语句支持字符串** - 在之前的Java版本中,`switch`语句只能处理`byte`, `char`, `short`, `int`, `枚举类型`。但在JDK 7中,`switch`语句可以直接处理`String`对象,这极大地提高了代码的可读性。 4. *...
6. **字符串处理**:`String`类在Java中是不可变的,提供了许多用于操作字符串的方法,如`substring()`、`concat()`和`indexOf()`等。 7. **异常处理**:Java使用异常处理来中断正常流程,处理程序运行时出现的问题...
【JAVA学习笔记】 Java是一种广泛使用的面向对象编程(OOP)语言,它的设计目标是提供高效、可...然而,仅阅读第一章并不能立即编写复杂的Java程序,后续章节将详细介绍更多的概念和示例,帮助读者逐步精通Java编程。
2.16 Java基础其他注意事项:学习过程中需要注意的其他事项,例如代码规范、性能优化建议等。 面向对象知识点: 3.1 类:类是Java语言中定义对象的模板或蓝图。 3.2 对象:对象是类的实例。 3.3 包:包是一种管理类...
10. **Java虚拟机(JVM)**:了解JVM的工作原理对于优化Java程序至关重要,可能包括内存模型(堆、栈、方法区)、垃圾回收机制和JVM调优。 11. **Java标准库**:Java API文档中包含了大量的类和接口,笔记可能会...
10. **JVM内部机制**:了解JVM的工作原理,包括类加载、内存模型、垃圾回收等,可以帮助优化程序性能,解决内存溢出等问题。但这部分内容相对深入,初学者可能不会立即接触到。 以上只是学习Java过程中容易被忽略的...
在内存管理和性能优化方面,笔记会涵盖Go的垃圾回收机制,以及如何通过内存分配策略和缓存管理来提升程序性能。此外,还会讲解Go的错误处理机制,包括错误的产生、捕获和处理,以及如何编写健壮的Go程序。 Go语言的...
实验内容被精心设计为九种类型,涵盖了从基本语法到高级主题的广泛范围,如数组与字符串处理、面向对象编程、异常处理、多线程编程等。 #### 二、实验指导1 JAVA语言概述 **知识点笔记:** - **Java语言简介**:...
4. **文本处理**:通过`CharCaseStats.java`了解如何在Java中处理字符串,进行字符统计。 5. **代码调试**:学习使用调试工具查找和修复代码错误。 6. **编程实践**:通过实际的代码编写,增强编程能力,可能包括...
- **改进的内存管理**:包括垃圾收集器的优化,提升了程序性能。 - **异常处理增强**:增加了Suppressed异常处理,使得处理多个异常更为便捷。 - **NIO.2**:新增了文件系统API,提供了更强大的非阻塞I/O操作。 - **...
- 本书深入介绍了Java的基础知识和技术细节,包括但不限于类、对象、数组、字符串处理等。 - 是一本非常适合中级学习者进一步深化理解的书籍。 ### 数据结构与算法 1. **数据结构与算法-JAVA语言版**: - 该...
1. 资源文件:Android应用中的图片、字符串、颜色、样式等资源都应放在特定的目录下,便于管理和复用。 2. 资源ID:Android编译系统会自动为资源分配ID,通过R类访问。 八、调试与性能优化 1. 调试工具:Android ...
9. **性能优化**:虽然Python是解释型语言,但可以通过生成C扩展、使用JIT编译(如Numba)或使用并行计算库(如multiprocessing)等方式提高性能。 10. **社区和工具**:Python拥有庞大的开发者社区,提供丰富的...
9. 性能优化:如果笔记深入,可能还会讨论JSON-lib的性能和优化技巧,比如批量转换、缓存策略等。 10. 其他相关工具:JSON-lib并不是唯一的JSON处理库,笔记可能还会对比其他如Jackson、Gson等框架,讨论它们的特点...