昨天看到一个blog,用一个极端例子来说明Java中的内存问题:
http://blog.xebia.com/2007/10/04/leaking-memory-in-java/
测试代码如下:
- public class TestGC {
- private String large = new String(new char[100000]);
-
- public String getSubString() {
- return this.large.substring(0,2);
- }
-
- public static void main(String[] args) {
- ArrayList<string></string> subStrings = new ArrayList<string></string>();
- for (int i = 0; i <1000000; i++) {
- TestGC testGC = new TestGC();
- subStrings.add(testGC.getSubString());
- }
- }
- }
-
如果要改掉这个bug,只要改写一下getSubString的方法就好了。
- public String getSubString() {
- return new String(this.large.substring(0,2));
- }
我测试了一下,确实如此。然后我看了一下JDK1.5.0_06代码中String类
from JDK1.5.0_06, String class:
- 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);
- }
这里用到的String的构造函数是private的
- private String(int offset, int count, char value[]) {
- this.value = value;
- this.offset = offset;
- this.count = count;
- }
上面那个例子程序改写的部分其实就是增加调用public的String构造函数另外创建一个String对象,我们再来看看这个public的构造函数,已经另外一个类似上面这个private的构造函数的public构造函数:
两个public的构造函数
- public String(String original) {
- int size = original.count;
- char[] originalValue = original.value;
- char[] v;
- if (originalValue.length > size) {
-
-
-
- v = new char[size];
- System.arraycopy(originalValue, original.offset, v, 0, size);
- } else {
-
-
- v = originalValue;
- }
- this.offset = 0;
- this.count = size;
- this.value = v;
- }
-
- public String(char value[], int offset, int count) {
- if (offset < 0) {
- throw new StringIndexOutOfBoundsException(offset);
- }
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
- }
-
- if (offset > value.length - count) {
- throw new StringIndexOutOfBoundsException(offset + count);
- }
- char[] v = new char[count];
- System.arraycopy(value, offset, v, 0, count);
- this.offset = 0;
- this.count = count;
- this.value = v;
- }
上面这两个public的构造函数,另外创建出来的String对象和原来的String对象并不共享其char数组的。而前面那个private的构造函数没有作arraycopy,是共享char其数组的。我想JDK这个实现有待商讨,内部使用的private的构造函数中不需要copy数组,可以共享数组。但private的构造函数被public的subString方法调用后,被外部使用时,就有问题了。
以后写相关代码时要小心了!
分享到:
- 2007-10-11 10:48
- 浏览 1400
- 评论(1)
- 论坛回复 / 浏览 (0 / 4376)
- 查看更多
相关推荐
JVM主要管理两种类型内存:堆和非堆,堆内存(HeapMemory)是在Java虚拟机启动时创建,非堆内存(Non-heap Memory)是在JVM堆之外的内存。简单来说,非堆包含方法区、JVM内部处理或优化所需的内存(如JITCompiler,...
String和StringBuffer、StringBuilder 在java性能测试中经常遇到很多的问题,Jason对代码端的非常常见的问题留下点Memory。 String和StringBuffer、StringBuilder 在循环中使用“+”来连接String将大大降低...
java分析工具(memory analyzer)是款功能非常强大的java监控分析工具;这款软件是作为跨平台的开源工具进行使用的,软件可以快速的进行分析您的内存问题,也可以进行监控整个的Java 应用程序的姿态和行为,并且还可以...
JAVA看不了字符串源码用法 源memory_leak_checker.js和来自JavaScript的调用: MemoryLeakChecker(window) 这将分析每个对象并列出并输出具有200多个元素的任何对象或列表。 这对于查找数据结构中的泄漏可能非常有用...
private long javacount; /** 可使用内存. */ private long totalMemory; /** 剩余内存. */ private long freeMemory; /** 最大可使用内存. */ private long maxMemory; /** 操作系统. */ private ...
简单内存编译器 这是javax.tools.JavaCompiler的... " public static void main(String args[]) { " + " A.print( \" Hello from an inner class \" ); " + " } " + " public static class A { " + " public stati
关于java的神话 这个项目是出于对Java的“本地”开发人员的沮丧而开始的 内存消耗 纯Java 由阻塞2分钟的一个“哑”主类组成 package org.deer.java8.memory.consumption ; import java.util.concurrent.TimeUnit ; ...
// buffer wrapped around the memory pointed by imageData, and under Android we can // also use that Buffer with Bitmap.copyPixelsFromBuffer() and copyPixelsToBuffer(). // - To get a BufferedImage ...
aboutCal = new JMenuItem(" 关于计算器(A)"); aboutCal.setForeground(Color.MAGENTA); aboutCal.addActionListener(this); myCollege =new JMenuItem(" 进入我的学院(W)"); myCollege....
實踐31:如欲進行字符串接合,StringBuffer優於String 107 實踐32:將對象的創建成本(creation cost)降至最小 109 實踐33:慎防未用㆖的對象(unused objects) 114 實踐34:將同步(synchronization)減至最低 ...
SimpleCacheA Cache framework for java and android application, objects are store in key-value pair in memory,value can be any java object like String, List, Map etc. you can define your store logic ...
public static void main(String[] args) { try { // System信息,从jvm获取 property(); System.out.println("----------------------------------"); // cpu信息 cpu(); System.out.println("------------...
问题如下; java.lang.ExceptionInInitializerError Caused by: java.lang.IllegalArgumentException: input == null! at javax.imageio.ImageIO.read(ImageIO.java:1388) at ...
Exception in thread “main” java.lang.UnsatisfiedLinkError: /tmp/OraInstall2009-11-25_02-34-42PM/jre/1.4.2/lib/i386/libawt.so:libXp.so.6: cannot open shared object file: No such file or directory ...
Java_Memory Java_Node Java_Photo_Base64AndZip Java_Request_GetIP Java_Shiro_Session Java_Singleton Java_Transient Java_URLConnection_File_Download Java_Volatile Java_jmap_histo_pid Java_jmeter_server_...
Guava: Google Core Libraries for Java Guava is a set of core libraries that includes new collection types (such as multimap and multiset), immutable collections, a graph library, functional types, ...
====== Java进程间持久性内存映射对象 实现的功能 使用内存映射文件(MMF); 线程安全的Evergreen 对象; 当跨多个JVM(通过使用目标MMF上的锁定位)进行访问时,可以安全地读取/写入文件中的已保存实例。 低...
在Java中想要使用这个数据文件需要下载相应的Jar包和dat文件: GeoIP jar包:geoip-api-1.3.1.jar Geo city dat文件:GeoLiteCity.dat 把dat文件放在自己的本地目录,然后项目中导入geoip.jar即可: import ...
private final String windowsParseMacAddress(String ipConfigResponse) throws java.text.ParseException { String localHost = null; try { localHost = java.net.InetAddress.getLocalHost().getHostAddress(); ...
用于存储普通的串口,可以基于java.lang.String。 列表对象,脆弱基于java.util.List; 哈希表结构,一直基于java.util.Map; 集合结构,暂时基于java.util.Set; 有序集合结构,并基于java.util.Map和跳跃表。 单...