最近在做一个游戏Demo,同时开始1000场比赛,过了有半小时,就出现了内存溢出情况。
在网上也java性能优化的帖子,在这里弱弱的问一下,SubString执行效率怎样,有看到帖子中说到
也会照成内存溢出???? 或者有没有更好的办法替代subString, 主要实现字符串的截取功能。
------解决方案--------------------
对字符串的频繁操作,建议若无并发时首选StringBuilder。。。。。。。。
------解决方案--------------------
《程序设计实践》中的《性能》那一章第一节用一个小例子谈到, 有些函数单独运行的效率是不错的, 但放到系统之中就可能就造成了效率底下,因为可能这些函数会重复很多操作; 推荐楼主看一下,或许会有帮助。 你可能需要根据自己的需求自己写一个
楼主没有指出应用背景, 别人也难以作答。 建议你将问题抽象一下, 抽取出一个跟应用背景无关的更清晰的问题表述,这样别人就容易给你更合适的答案了。并且,你为什么要怀疑 subString 的效率呢?
------解决方案--------------------
1 想象不出“溢出”(Overflow)的可能OutOfMemory倒是有那么一点点.......点可能
2 效率还是可以的
String的字段重点是3个
char[] value; // 用以存放字符
int offset; // 记录当前字符串在value的开始位置
int count; // 当前字符串的长度,也就是.length()对应的值。
String b = a.substring(3, 10)的时候,
a.value 直接赋值给b.value,也就是说两者共享的是同一个char[],只是b.offset = 3, b.count = 7
同理String c = b.substring(1, 2),c还是共享同一个char[],只是c.offset = 4, c.count = 1
------解决方案--------------------
subString 没有错, 问题是楼主是怎么运用 subString 的, 不知道你怎么使用这个函数, 就难以理解为什么使用这个函数会造成溢出。 还是说得更详细一点吧。 在循环里多次调用 subString 怎么个多次, 怎么个调用法? 会不会创造了太多的String 对象; 是否有非常纠结的循环? 是否可能由其它地方导致 ?
我内存溢出时, 通常都是为了想看看算法的复杂度,分配 n = 10000000 的数组才会导致溢出。 有时候,是否可能创造了太多多余的数组, 这也可能导致溢出。
------解决方案--------------------
可能什么地方的String累加值过大超出了默认给的内存就挂了。
------解决方案--------------------
懂些内存优化方面的知识很重要,建议楼主找找...
------解决方案--------------------
substring()返回的字符串并不会真正复制原字符串的byte数组的一部分,而只是指向原字符串的byte数组的某个区间,这个特性决定了它的执行效率是很不错的,在内存使用方面则根据具体情况可能有两极化的表现。
一般来说,由于substring()没有为子字符串申请新的空间,它有节约内存空间的作用。
但在有些情况下,它反而浪费内存空间,因为它会导致它所基于的原字符串无法释放,从而不能被垃圾回收,如:
public String getSub() {
String total=.......
return total.substring(0,1);
}
String sub = getSub();
total本来是个局部变量,getSub()结束就可以被释放,但由于sub的存在,它无法被释放。如果total是个很长的字符串,sub相对来说短得多,就不是好事了。
要解决这个问题也很简单,用intern()就可以了,如:
public String getSub() {
String total=.......
return total.substring(0,1).intern();
}
String sub = getSub();
这时系统会为sub的数据单独开辟一个独立的内存空间,原字符串total在getSub()结束就可被垃圾回收了。
总的来说,还是要具体情况具体分析,灵活运用,并没有一定的答案,关键是理解背后的机制。
------解决方案--------------------
留上的例子不错。
不过有个疑问
total.substring(0,1).intern();每次的内容不一样。字符串池也会不会爆掉啊
------解决方案--------------------
又去翻了下api:
Returns a new string that is a substring of this string.
照这句,感觉是total会被回收的吧。
- Java code
public String getSub() { String total=....... return total.substring(0,1);}String sub = getSub();
------解决方案--------------------
Out Of Memory
效率肯定不差
------解决方案--------------------