Redian新闻
>
请问StringBuffer的OutofMemory问题
avatar
请问StringBuffer的OutofMemory问题# Java - 爪哇娇娃
s*t
1
这段MV是2003还是2004的欧洲音乐典礼作为嘉宾的一段,当时我在电视上看的直播,现
在居然在youtube上找得到。记得主持人在介绍他们之前说了一段挺有意思的,大意是
“我们将要介绍我们的表演嘉宾,喜欢他们的人把他们当作神,憎恶他们的把他们当垃
圾。。。”
这首歌并不是Rammstein最出彩的,我还是喜欢Mutter最多,然后Amerika因为歌词我也
比较喜欢,但是每次听Ich Will我就想到Savage Garden的I want you,可能是歌名相似
,也可能是两首歌的MV都是让人记忆深刻,更可能是I Want You是我当年接触Savage
Garden的第一首歌,而Ich Will也是我认识Rammstein的第一首,第一次总是让人难忘
的,无论美好与丑恶,特别抑或是平庸。。。
avatar
b*8
2
我先是读取一个一个文本文件,每行15字符,文件的行数可能有几十万。然后需要把每
一行连起来。本来是用的
string s = "";
s = s + stringtoadd;
问题是这个东西特别慢,后来我查了下可以用StringBuffer,用它的append方法,每次
调用sb.append(stringtoadd)
这个速度比String+要快多了。可是又出现了新问题,总是提示:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unk
avatar
s*e
3
以前看过一片文章,说Rammstein歌词发音都是古德语式的,非常纯正典雅
他们演唱会很是出彩,记得有次最后一首是seaman,吉他手坐着皮艇绕场一周
全靠人群在下面传递,把我看的一愣一愣的。
还有人觉得他们的演唱会是纳粹式的仪式

【在 s*********t 的大作中提到】
: 这段MV是2003还是2004的欧洲音乐典礼作为嘉宾的一段,当时我在电视上看的直播,现
: 在居然在youtube上找得到。记得主持人在介绍他们之前说了一段挺有意思的,大意是
: “我们将要介绍我们的表演嘉宾,喜欢他们的人把他们当作神,憎恶他们的把他们当垃
: 圾。。。”
: 这首歌并不是Rammstein最出彩的,我还是喜欢Mutter最多,然后Amerika因为歌词我也
: 比较喜欢,但是每次听Ich Will我就想到Savage Garden的I want you,可能是歌名相似
: ,也可能是两首歌的MV都是让人记忆深刻,更可能是I Want You是我当年接触Savage
: Garden的第一首歌,而Ich Will也是我认识Rammstein的第一首,第一次总是让人难忘
: 的,无论美好与丑恶,特别抑或是平庸。。。

avatar
h*0
4
有几个地方可以优化。
1. 用StringBuilder, 用法跟StringBuffer一样,但速度更快。
2. sb.append("(" + list.get(j) + "),");
要改成:
sb.append("(");
sb.append(list.get(j));
sb.append("),");
这样可以减少内存消耗。
3. 最后,如果还是会out of memory,那就试着不要先读文件存入list中,而是直接读
一行append一行。
4. 最最后,如果还是不行,你分析一下。默认内存(堆)只有64M,是不是不够?如果
不够,运行程序时java命令加入参数指定更大的内存(堆)。

【在 b********8 的大作中提到】
: 我先是读取一个一个文本文件,每行15字符,文件的行数可能有几十万。然后需要把每
: 一行连起来。本来是用的
: string s = "";
: s = s + stringtoadd;
: 问题是这个东西特别慢,后来我查了下可以用StringBuffer,用它的append方法,每次
: 调用sb.append(stringtoadd)
: 这个速度比String+要快多了。可是又出现了新问题,总是提示:
: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
: at java.util.Arrays.copyOf(Unknown Source)
: at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)

avatar
m*t
5
What are you planning on doing with this one huge line after this,
if you don't mind me asking?

【在 b********8 的大作中提到】
: 我先是读取一个一个文本文件,每行15字符,文件的行数可能有几十万。然后需要把每
: 一行连起来。本来是用的
: string s = "";
: s = s + stringtoadd;
: 问题是这个东西特别慢,后来我查了下可以用StringBuffer,用它的append方法,每次
: 调用sb.append(stringtoadd)
: 这个速度比String+要快多了。可是又出现了新问题,总是提示:
: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
: at java.util.Arrays.copyOf(Unknown Source)
: at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)

avatar
s*e
6
You should know how jvm is supposed to handle string before you use java
string/stringbuilder/stringbuffer in this way.
Java uses string pool to handle string operation to improve the performance.
By appending string to old string, you are incrementally creating new
string objects in string pool, for example, you first line is a, you will
have one entry as a in the pool, then you append b to a, now you have two
strings of a and ab in the pool, etc.
Depending on jvm implementation, the gc mechani
avatar
b*8
7
谢谢你的回复啊
我现在一个变通的办法是一次只读取20000行进行处理,然后就把这个StringBuffer
reset 再重新读2000行这样,回头我试一试StringBuilder

谢谢,我用这个试试
读入的文件都不大,总共也就40MB左右,为什么会这么容易out of memory?文件从硬盘
中读入内存会因为格式不同占用多得多的memory吗?
这个我已经改过了,初始的时候就有768MB

【在 h*****0 的大作中提到】
: 有几个地方可以优化。
: 1. 用StringBuilder, 用法跟StringBuffer一样,但速度更快。
: 2. sb.append("(" + list.get(j) + "),");
: 要改成:
: sb.append("(");
: sb.append(list.get(j));
: sb.append("),");
: 这样可以减少内存消耗。
: 3. 最后,如果还是会out of memory,那就试着不要先读文件存入list中,而是直接读
: 一行append一行。

avatar
b*8
8
你说的是不是不应该把string s 用来循环增加?
记住了

performance.

【在 s******e 的大作中提到】
: You should know how jvm is supposed to handle string before you use java
: string/stringbuilder/stringbuffer in this way.
: Java uses string pool to handle string operation to improve the performance.
: By appending string to old string, you are incrementally creating new
: string objects in string pool, for example, you first line is a, you will
: have one entry as a in the pool, then you append b to a, now you have two
: strings of a and ab in the pool, etc.
: Depending on jvm implementation, the gc mechani

avatar
b*8
9
之前的数据都是放在文本文件里面的,是一组信号的时间序列,是我现在需要把他们搞
到数据库里面去
我查到mysql可以有一个句法可以一次插入很多行,所以就想一次把数据都读出来然后
写一个超长的insert命令加到database里面去

【在 m******t 的大作中提到】
: What are you planning on doing with this one huge line after this,
: if you don't mind me asking?

avatar
g*g
10
bad idea, you don't need to insert many lines at one sql first of
all, as long as it's in one transaction, it's probably as fast.
I would do one line per sql, but batch them up, e.g. commit once
every 100 lines.

【在 b********8 的大作中提到】
: 之前的数据都是放在文本文件里面的,是一组信号的时间序列,是我现在需要把他们搞
: 到数据库里面去
: 我查到mysql可以有一个句法可以一次插入很多行,所以就想一次把数据都读出来然后
: 写一个超长的insert命令加到database里面去

avatar
s*i
11
每一行改写成一条mysql query,用insert delay
然后直接往mysql里面导入就是了,非常快

【在 b********8 的大作中提到】
: 之前的数据都是放在文本文件里面的,是一组信号的时间序列,是我现在需要把他们搞
: 到数据库里面去
: 我查到mysql可以有一个句法可以一次插入很多行,所以就想一次把数据都读出来然后
: 写一个超长的insert命令加到database里面去

avatar
n*n
12
insert delay是不是jdbc 2.0的东西?

【在 s*****i 的大作中提到】
: 每一行改写成一条mysql query,用insert delay
: 然后直接往mysql里面导入就是了,非常快

avatar
s*i
13
mysql的

【在 n*********n 的大作中提到】
: insert delay是不是jdbc 2.0的东西?
avatar
m*t
14

You might consider batch insert as bug suggested. It's standard jdbc api
supported by all major vendors now.

【在 b********8 的大作中提到】
: 之前的数据都是放在文本文件里面的,是一组信号的时间序列,是我现在需要把他们搞
: 到数据库里面去
: 我查到mysql可以有一个句法可以一次插入很多行,所以就想一次把数据都读出来然后
: 写一个超长的insert命令加到database里面去

avatar
b*8
15
谢谢各位的帮助!

【在 m******t 的大作中提到】
:
: You might consider batch insert as bug suggested. It's standard jdbc api
: supported by all major vendors now.

avatar
m*e
16
Allocate StringBuffer at the beginning so that it does not copy the char
array:
StringBuffer sb = new StringBuffer(15*500000);
That's about 10MB. Should be fine.
But then insert has its own max length...
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。