今天在工作中遇到一个问题,花了很久才解决,现在与大家分享一下。
问题的具体情况是这样的,我们的程序会从一个文本文件中读取数据。这个文件每行大概有1000个字符左右,但是我们需要的只是其中固定位置的10个字符左右的一段数据。具体的做法是每次都读取一行,然后使用subString来获取我们需要的值。之后将原来的大的字符串抛弃,将读取的小的字符串保存在一个Set中。
这段逻辑在进行JUnit测试的时候没有发现什么问题,但是在进行大数据量的性能测试的时候,确出现了占用大量内存的问题(远远超出了我们估计的内存使用量)。使用内存分析工具来查看,发现保存在Set中的字符串对象的大小明显异常。这是为什么呢?
我们使用Debug来检查这段代码,发现一个奇怪的问题。我们从一个1000字符的字符串中subString了一段10字符的字符串。但是查看subString的value属性的时候,value还是一个1000字符的字符数组,而不是我们想象中的10个字符的字符数组。这是为什么呢?
Code just do what you tell it to do. 代码只会做你让它做的事情。那么就让我们看看Java的源码吧。下面就是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);
- }
复制代码
看看倒数第二行,这就是原因。Java源码并不是我们想象的那样将原来的字符串的value截取一段赋给新的字符串,而是直接将原来字符串的value赋给新字符串,然后通过制定offset和length的方法来创建新的字符串。原因找到了,修改起来就很简单,不必多说了。
Java这样做的好处是避免了内存的拷贝,对于String这样很基础的类来说,这样可以提高程序的效率。但是这个小小的“陷阱”,花费了我半天的时间。
分享到:
相关推荐
在Java编程语言中,`substring()`方法是字符串类(String)的一个重要成员,它用于从原始字符串中提取子串。这个方法非常实用,特别是在处理文本数据时,我们需要根据特定的需求截取字符串的一部分。下面我们将详细...
Java 中由 substring 方法引发的内存泄漏详解 Java 中的 substring 方法是一个非常常用的字符串操作方法,但是在 JDK 1.6 中,如果不当使用该方法,可能会导致严重的内存泄漏问题。下面我们将详细介绍 Java 中由 ...
Java 中的 substring 与 substr 方法 Java 语言中提供了两种截取字符串的方法:substring 和 substr,这两种方法都是用于从字符串中提取指定范围的子字符串。下面对这两种方法的用法进行详细介绍: substring 方法...
在IT领域,数据库是存储和管理数据的核心工具,而`substring`函数是数据库查询中一个非常...在实际工作中,结合源码理解和使用工具,如SQL查询优化器,可以帮助我们更好地掌握`substring`的使用方法,提升工作效率。
在Java编程语言中,`String`类提供了多种方法来操作字符串,其中`substring()`方法用于截取字符串中的某一部分。它有两种重载形式,分别是单参数和双参数。 1. **单参数substring方法**: `public String ...
在操作sqlserver时候用到了substring函数 SUBSTRING ( expression, start, length ) 参数 expression 字符串、二进制字符串、文本、图像、列或包含列的表达式。请勿使用包含聚合函数的表达式。 start 整数或可以隐式...
本文将深入探讨JavaScript中的`substr()`和`.NET`中的`substring()`方法,以及它们之间的区别。 ### JavaScript中的`substr()`方法 在JavaScript中,`substr()`方法用于提取字符串中的一部分。它接受两个参数:...
在本教程中,我们将深入探讨如何使用`substring()`方法来提取`String`对象中的子串。 `substring()`方法主要有两种形式: 1. `substring(index)` 2. `substring(startIndex, endIndex)` 这两种形式都是用来从原始...
在处理字符串时,我们经常需要从一个长字符串中提取出一部分子串,这时`String` 的 `substring()` 方法就显得尤为重要。本文将深入探讨`substring()` 方法的用法和注意事项。 `substring()` 方法有两种重载形式,一...
在JavaScript中,字符串对象提供了两种用于提取字符串部分的方法:substring()和substr()。它们的主要用途是提取字符串中的特定部分,但是它们的工作方式和参数的使用是不同的。下面将详细介绍substring()和substr()...
### Oracle中的SUBSTR函数详解 在Oracle数据库中,`SUBSTR`函数是一个非常重要的字符串处理函数,用于从指定的字符串中提取子串。该函数在实际应用中极为广泛,能够帮助用户灵活地处理数据,满足各种业务需求。下面...
java 中的字符串处理是编程中最基本也是最重要的一部分,substring 和 substr 两个方法是 java 中最常用的字符串处理方法。在本文中,我们将详细介绍 substring 和 substr 两个方法的定义、用法、参数、返回值、说明...
在编程领域,特别是涉及到文本处理的时候,`substring`方法是一个非常常见且重要的工具,它用于从一个字符串中截取部分子字符串。这个方法在Java、JavaScript等许多编程语言中都有提供,我们主要以Java为例来详细...
在 Java 中,substring 方法的实现原理是不同的版本的 JDK 中实现方式各不相同。了解这些差异可以帮助我们更好地使用 substring 方法。 JDK 6 中的 substring 实现 在 JDK 6 中,String 类包含三个成员变量:char ...
实现一个按字节来截取字符串的方法,功能类似于string类的substring方法,String类是按字符截取 的,例如"中国abc".substring(1,3),将返回“国a”。这里 要求按字节截取,一个英文字符当一个字节,一个中文字符当两...
SQL 中的 substring 函数是用来抓出一个栏位资料中的其中一部分。这个函数的名称在不同的资料库中不完全一样: 参数: expression 字符串、二进制字符串、文本、图像、列或包含列的表达式。请勿使用包含聚合函数...
JavaScript 中的 substring 和 substr 区别与使用方法 在 JavaScript 中,substring 和 substr 是两个常用的字符串截取方法,但是它们之间存在着一些区别和使用方法的不同。本文将详细介绍 JavaScript 中 substring...
Substring截取字符串字符串截取方法是计算机编程中一种常见的操作,它指的是从字符串中提取某一段子字符串,在不同的编程语言中有不同的实现方式。下面将介绍Substring截取字符串字符串截取方法的定义、实现方式和...
标题中提及的JavaScript中的indexOf、lastIndexOf和substring方法是字符串对象提供的几个基础且非常有用的方法,用于搜索字符串中的子字符串位置或者截取字符串。以下是对这些方法的详细知识点解说。 首先,讨论...
在Java编程语言中,`substring()`方法是字符串类`String`的一个重要成员,用于从原始字符串中截取子字符串。这个方法提供了灵活的截取方式,使得开发者可以根据需要选择截取字符串的不同部分。以下是关于`substring...