`
cloudtech
  • 浏览: 4612963 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

也来说说java Memory Leak

 
阅读更多

Java有内存泄漏吗?有。虽然有人说这个说法不准确,但是在C/C++程序中,我们把由当前进程开辟但当前进程在逻辑上却无法再管理的那些内存称为被进程泄漏的内存。事实上java同样会有这样的情况。

当我们最先接触java时就因为它自动管理内存不需要程序员手工干预而带来的方便性的原因喜欢上了它,但这个自动并不是全能的。对于一些隐性引用所引起的内存泄漏,有时很长时间甚至几个月,几年我们也很难发现,除非是非常有经验的人去仔细地查看源码,借用heap分析工具细致地分析才能发现。

最简单的java内存泄漏是一种数据结构的实现。比如:

InnerStack<E>{

privateintsize = 32;

privateos

@SuppressWarnings"unchecked" InnerStack(){

osnewINITIALCAPACITY }

publicvoid checkCapacity();

thisossize }

E pop(){

ifsizethrownew E o = (E).[--];

thisossizenull o;

public ( <= 0) EmptyStackException();

thisosthissize o;

@SuppressWarnings"unchecked" checkCapacity(){

ifsizeoslength = (E[]) Object[ * 2 + 1];

}

JAVAtype var = null;这种语法,但在自己实现的数据结构中,如果上例注释os[10]指向的对象被InnerStack中还有一个内部数组中有一个引用指向它,这个对象被不能在调用者使用完后立即标记为可回收。

如果同样的方法实现循环队列,情况还有些好转,即使没有打断引用,当入队的元素多于数据长度时原来的引用就会被后来入队的引用覆盖掉。但对于自动扩展的栈来说,如果某一时刻容量到了一个峰值,比如底层数组长被扩展到os[64]如果os[64] = null;那么以后在很长时间不会再访问到这个位置(峰值嘛)那么它指向的对象虽然在外部已经“使用”完成了,但却无法被回收,别小看这几个对象,因为它们还会引用别的对象。关系很复杂,可能会造成很大的内存泄漏。

List等对象支持,如果对象被获取后,底层的对象容器是否及时地clear,都会造成对象被无意地引用而不能被回收。需要把一些对象先缓存起来然后再获取使用的时候,最好是能选择象

ListenersListenerListener是和应用的生命周期相同,除非你在退出之前的逻辑中处理它们,否则它们没有被回收的理由。但是真正引起大量的内存泄漏的实际应用中,

在很多时间,IO通道一次不能读取完成完成所有传输的数据,那么我们无论把已经有的数据缓在自己的数据结构中和attachKey对应的客户端有可能在非常恶劣的网络下或干脆断线,你所注册的事件根本就没有返回结果,则保存原来的数据永远没法处理。对于写出操作同样有这样的问题。所以一定要在把开始注册的时间和attach

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics