今天用线程做视频转码的时候,爆出了一个错误:java.lang.OutOfMemoryError: Java heap space
我没有懊恼,反而很开心,终于遇到你了,内存溢出(堆内存溢出)!
上图:
报错信息:
这个错误是年老代堆空间被占满:这是最典型的内存泄漏方式,简单说就是所有堆空间都被无法回收的垃圾对象占满,虚拟机无法再在分配新空间
代码:
@Override
public void run() {
StringBuffer msgBuffer = new StringBuffer();
try {
if (ffmpegConfig != null && ffmpegConfig.isDebug()) {
logger.info("线程启动:[{}]", id);
while (downloadStatus) {
if (Strings.isNotEmpty(br.readLine())) {
ohm.parse(id, br.readLine());
}
msgBuffer.append(br.readLine());
}
if (!downloadStatus) {
logger.info("线程停止:[{}]", id);
}
} else {
Thread.yield();
}
} catch (IOException e) {
stop();
throw new CameraException("IOException===>" + e.getMessage());
} finally {
stop();
}
}
这段代码写的比较low,但是不妨碍找到内存溢出的问题点,就在我创建的StringBuffer上,
msgBuffer.append(br.readLine());
这个语句只要线程不停,就会一直append,导致StringBuffer一直在变大,耗费内存。
查看了一下源码,是在扩充内存的时候报的错误:
红框里面的意思是最小扩容比整型的最大值还要大,因此报了OOM异常。
注:Integer.MAX_VALUE的最大值是2的31次方 -1
/**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1.
*/
@Native public static final int MAX_VALUE = 0x7fffffff;
解决办法:根据垃圾回收前后情况对比,同时根据对象引用情况(常见的集合对象引用)分析,基本都可以找到泄漏点。我的解决办法是去除这个无用的Stringbuffer
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/158170.html