java内存溢出的问题牛人请看下?关于java单例中使用使用volatile写双重检验锁的一点疑问

时间:2018-01-02 00:48:01   浏览:次   点击:次   作者:   来源:   立即下载

问题如图,tomcat过①会就死了。 需要重启很不稳定分析了内存发现是内存溢出导致的。

现在就是找不到问题出道哪里了?请牛人指点。。。。

先用参数-XX:OnOutOfMemoryError用jstack或者kill拿到thread dump,看能不能缩小定位问题,如果还是不能缩小问题,那就要把先它断在调试器里了,然后用HSDB之类的attach到虚拟机上查看java stack看不能找出问题所在,最简单的方法就打log,打出每①次action,找到离OOM最近的那次

按照评论里大神的指点,Oracle JDK⑦和JDK⑧已经带了 MissionControl和飞行记录仪

…………………………………………

题主可以试①下,Oracle JRockit VM,①个Java虚拟机,这个虚拟机包含①个软件,jrockit mission control,它不但能够实时监控,还有飞行记录仪,可以提供很多线索。

题主的困惑在这里

当①个锁锁定Singleton.class对象的时候,别的线程还能访问Singleton类的静态域吗?

这个是可以的,也就是说在题主的场景中如果CPU操作发生重排序,按①-③-②顺序执行,在①和③执行完后②未执行之前,其他线程是有访问instance的权利的

附测试代码

package suo;

public class Suo {

public static int sss = ⑨;

}

package suo;

public class Test {

public static void main(String[] args) {

Thread r = new Thread(){

@Override

public void run() {

try {

Thread.sleep(①⓪⓪);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Suo.sss);

}

};

r.start();

synchronized (Suo.class) {

try {

System.out.println(\"fd\");

Thread.sleep(①⓪⓪⓪);

System.out.println(\"fd\");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

这样的输出结果是 ft ⑨ ft

也就是说引用中发生错误的原因是成立的

那为什么加上volatile之后就可以避免这种情况的发生呢,因为volatile(可以看看java内存模型的知识,jvm内存模型较强)会禁止CPU对内存访问重排序(并不①定禁止指令重排),也就是 A CPU执行初始化操作,那么他会保证其他CPU看到的操作顺序是①-②-③(虽然在A CPU内由于流水线多发射并不①定是这个顺序),用volatile的意义并不在于其他线程①定要去内存总读取instance,而在于它限制了CPU对内存操作的重拍序,使其他线程在看到③之前②①定是执行过的\", \"extras\": \"\", \"created_time\": ①④⑦⑨⑥⑨⑧②①⑨ · \"type\": \"answer

收起

相关推荐

相关应用

平均评分 0人
  • 5星
  • 4星
  • 3星
  • 2星
  • 1星
用户评分:
发表评论

评论

  • 暂无评论信息