`
sw1982
  • 浏览: 511341 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

恐怖的string+操作消耗

阅读更多

偶然翻到一本书,《Java程序员上班那点事儿》,按照其第四章的实例代码跑了一下string的“+”操作,测试数据真的有点恐怖。。

 

 

public class MemoryTest {
	public static void main(String args[]) {
		String s = "abcdefghijklmnop";
		System.out.print(" 当前虚拟机最大可用内存为 :");
		System.out
				.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "M");
		System.out.print(" 循环前,虚拟机已占用内存 :");
		System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024
				+ "M");
		int count = 0;
		while (true) {
			try {
				s += s;
				count++;
			} catch (Error o) {
				System.out.println(" 循环次数 :" + count);
				System.out.println("String 实际字节数 :" + s.length() / 1024 / 1024
						+ "M");
				System.out.print(" 循环后,已占用内存 :");
				System.out.println(Runtime.getRuntime().totalMemory() / 1024
						/ 1024 + "M");
				System.out.println("Catch 到的错误 :" + o);
				break;
			}
		}
	}
}

 

 

默认情况下:

 

 当前虚拟机最大可用内存为 :63M

 循环前,虚拟机已占用内存 :4M

 循环次数 :19

String 实际字节数 :8M

 循环后,已占用内存 :63M

Catch 到的错误 :java.lang.OutOfMemoryError: Java heap space

 

 

配置Xms=1248m之后:

 

当前虚拟机最大可用内存为 :1238M

 循环前,虚拟机已占用内存 :4M

 循环次数 :23

String 实际字节数 :128M

 循环后,已占用内存 :1238M

Catch 到的错误 :java.lang.OutOfMemoryError: Java heap space


那么StringBuffer的数据是不是就会好看了?运行一下下面这个代码,也会让人吃惊的:
public class MemoryTest2 {
	public static void main(String args[]) {
		StringBuffer s = new StringBuffer("abcdefghijklmnop");
		System.out.print(" 当前虚拟机最大可用内存为 :");
		System.out
				.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "M");
		System.out.print(" 循环前,虚拟机已占用内存 :");
		System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024
				+ "M");
		int count = 0;
		while (true) {
			try {
				s.append(s);
				count++;
			} catch (Error o) {
				System.out.println(" 循环次数 :" + count);
				System.out.println("String 实际字节数 :" + s.length() / 1024 / 1024
						+ "M");
				System.out.println(" 循环后,已占用内存 :");
				System.out.println(Runtime.getRuntime().totalMemory() / 1024
						/ 1024 + "M");
				System.out.println("Catch 到的错误 :" + o);
				break;
			}
		}
	}
}
 
 当前虚拟机最大可用内存为 :63M
 循环前,虚拟机已占用内存 :4M
 循环次数 :20
String 实际字节数 :16M
 循环后,已占用内存 :63M

通常我们自认为看过一些文档就了解了全部真相,却未成去尝试“定量”分析。看到这个测试的数值之后还是触动很大的。当然,也说明这本书还是值得买一本看看的,绝对不是那种《java程序员面试宝典》之类的肤浅流派。
分享到:
评论
3 楼 timetenplus 2010-06-22  
这本书我也看过,确实不错。
2 楼 sw1982 2010-05-08  
System.out.println(s.length()); System.out.println(s.getBytes().length);
在我的环境上,上面两个长度是一致的。string变成byte的长度,跟字符集有关,
不知云 写道
研究了半天BZ的东西,发现楼主计算String的字节数有误。
String、StringBuffer包含的是char数组,而char是双字节的。所以BZ最后计算的 StringBuffer 实际字节数 :16M ,实际长度是32M。StringBuffer在append时,发现数组不够常重新申请新数组时,造成内存不够而导致溢出。
所以实际长度是32M没问题。

1 楼 不知云 2010-05-07  
研究了半天BZ的东西,发现楼主计算String的字节数有误。
String、StringBuffer包含的是char数组,而char是双字节的。所以BZ最后计算的 StringBuffer 实际字节数 :16M ,实际长度是32M。StringBuffer在append时,发现数组不够常重新申请新数组时,造成内存不够而导致溢出。
所以实际长度是32M没问题。

相关推荐

    区分java中String+String和String+char

    本文将深入探讨`String+String`和`String+char`这两种不同操作之间的区别。 首先,我们要理解Java编译器的优化机制。在Java中,如果两个`String`对象通过`+`运算符连接,如`"abc" + '/'`,编译器会自动进行字面量...

    测试string的+和String.Format()和StringBuilder.Append()性能差距|TestForString.7z

    测试结果可能会显示,在大量连接操作中,`StringBuilder.Append()`的速度可能是`+`或`String.Format()`的数倍。 总结起来,当进行字符串操作时,应根据具体需求选择合适的方法。如果只是简单的字符串连接,`+`...

    string对象的操作pdf

    ### string对象的操作详解 #### 一、string 类型简介及基本操作 在现代 C++ 编程中,`std::string` 是一个极其重要的类,它提供了丰富的接口用于字符串的处理,大大简化了字符串操作的复杂性。下面将详细介绍 `std...

    C++ 中重载 + 操作符的正确方法

    ### C++ 中重载 + 操作符的正确方法 #### 引言 在C++编程中,重载操作符是一项非常实用且强大的功能,能够帮助程序员以自然的方式处理自定义数据类型。对于像`+`这样的操作符而言,正确地进行重载尤为重要,因为它...

    自己封装String类

    实现各种操作符,+ ,=;string++ ; ++string ; ; >>; <; >; +=; -=; -; ==; 拷贝函数;append;insert;delete;reverse;display,replace;

    c# string操作,去除重复的串

    C#中的`string`类提供了丰富的内置方法,如`Substring()`, `Trim()`, `ToLower()`, `ToUpper()`, `Replace()`, `Split()`, `Join()`, `IndexOf()`, `LastIndexOf()`等,用于字符串的截取、清理、转换、查找和分割等...

    string 函数操作代码

    本篇文章将详细探讨`string`函数操作代码相关的知识,帮助你更好地理解和运用这些功能。 一、字符串的创建与初始化 在不同语言中,创建字符串的方式有所不同。例如,在Python中,可以直接通过引号创建: ```python ...

    String对象创建问题

    这种方式创建的`String`对象不会共享,所以可能会消耗更多的内存。 此外,`String`对象还可以通过`StringBuffer`或`StringBuilder`类进行动态构建,尤其是在需要拼接多个字符串时。这两个类提供了`append()`方法,...

    一个超简单的FIFO在QT里验证了

    // debugstring=debugstring+" None"; }else { wdex++; if(wdex>=rwmax)wdex=0; unsigned char ysdex=0;//原来的下标 debugstring=debugstring+"["+QString::number((wdex>0)?(wdex-1):(rwmax-1))+"] +1--&gt...

    string和char*

    string、CString 和 char* 的主要区别在于内存管理和字符串操作方式。 * string 自动管理内存,避免了手动释放内存的风险。 * CString 需要手动释放内存,但提供了许多实用的成员函数。 * char* 需要手动管理内存,...

    C语言实现String操作

    C语言简单实现String, 提供String基础唱作, 如 s_append / s_trim / s_split 等

    C#中char[]与string之间的转换 string 转换成 Char[]

    C#中char[]与string之间的转换是一种常见的操作,我们经常需要在这两种数据类型之间进行转换。今天,我们将探讨C#中char[]与string之间的转换,包括string转换成Char[]和Char[]转换成string,同时也会涉及到byte[]与...

    C++string类型的使用总结

    本篇总结旨在详细介绍`string` 类的构造方法、常用操作方法及其功能特性。 #### 一、`string` 类对象的构造 `string` 类提供了多种构造方法来创建`string` 对象,每种构造方法都有其特定的用途: 1. **无参构造**...

    大数据hbase测试项目, String boot + hadoop + hbase 的一个测试项目

    大数据hbase测试项目, String boot + hadoop + hbase 的一个测试项目 1.jdk路径不能有空格,中文 2.spring 示例官方xml配置中需有调整,避免 delete xxx 异常。 3.maven本地版本不能小于cm上hadoop、hbase版本。

    C++ String 详解 C++ String 详解

    C++ String 详解可以自动管理内存,避免了内存泄露和溢出的问题,同时也提供了许多实用的操作函数,使得字符串操作变得更加简单和高效。 C++ String 详解的优点在于,它不需要担心内存的分配和释放,字符串的长度也...

    stl string常用函数

    STL String 类是一个基本的字符串类,提供了多种构造函数、字符操作、输入输出操作、赋值操作、连接操作和比较操作等功能。 构造函数 STL String 类提供了多种构造函数,可以根据不同的需求选择合适的构造函数。...

    c++string用法详解

    特别是 C++ 的 string 类,它提供了许多实用的函数和操作符,极大地方便了字符串的处理。 1. String 的存储功能 C++ 的 string 类可以存储字符串,并提供了许多函数来操作字符串,如 substr()、find()、getline() ...

    String和string区别以及string详解

    在编程领域,尤其是在C#语言中,`String`和`string`经常被...在ASP.NET和SQL数据库操作中,`string`是构建动态查询和处理网络数据的关键元素。理解和熟练运用`string`类型,对于提升编程技能和解决实际问题至关重要。

    String[] list 相互转化

    ### String[] 与 List 相互转化 在 Java 编程语言中,`String[]` 数组和 `List` 集合之间的相互转换是非常常见的需求。这两种数据结构各有优势:数组提供了固定长度且访问效率高的特性,而列表则支持动态调整大小...

Global site tag (gtag.js) - Google Analytics