Java常见问题分析(内存溢出、内存泄露、线程阻塞等)
- Java垃圾回收机制(GC)
1.1 GC机制作用
1.2 堆内存3代分布(年轻代、老年代、持久代)
1.3 GC分类
1.4 GC过程 - Java应用内存问题分析
2.1 Java内存划分
2.2 Java常见内存问题
2.3 ML(内存泄露) OOM(内存溢出)问题现象及分析
2.4 IBM DUMP分析工具使用介绍 - Java应用CPU、线程问题分析
Java垃圾回收机制(GC)
1.GC机制作用
1.1 JVM自动检测和释放不再使用的对象内存
1.2 Java 运行时JVM会执行 GC,不再需要显式释放对象
例:Object.finallize()、 Windows.dispose()、 System.gc()
2.Java堆3代分布
关于Java堆3代分布情况,可通过命令:jmap –heap pid 查看
3.GC分类
3.1 Young GC(Minor GC):收集生命周期短的区域(Young)
(1) 清空Eden+from survivor中所有no ref的对象占用的内存
(2) 将Eden+from survivor中所有存活的对象copy到to survivor中
(3) 一些对象将晋升到old中: to survivor放不下的或存活次数超过turning threshold中的
3.2 Full GC(Major GC):收集生命周期短的区域(Young)和生命周期比较长的区域(Old),对整个堆进行垃圾收集,有时也会回收持久区(Perm)
(1) 清空heap中no ref的对象
(2) 清空permgen中已经被卸载的class信息
4.GC过程
(1) 新生成的对象在Eden区完成内存分配
(2) 当Eden区满,再创建对象,会因为申请不到空间触发YGC,进行young(eden+1survivor)区的垃圾回收(为什么是eden+1survivor:两个survivor中始终有一个survivor是空的,空的那个被标记成To Survivor)
(3) YGC时,Eden不能被回收的对象被放入到空的survivor(也就是放到To Survivor,此时Eden被清空),另一个survivor(From Survivor)里不能被GC回收的对象也会被放入To Survivor,始终保证一个survivor是空的(YGC完成之后,To Survivor 和 From Survivor的标记互换)
(4) YGC结束后,若存放对象的survivor满,则这些对象被copy到old区,或者survivor区没有满,但是有些对象已经足够Old(超过XX:MaxTenuringThreshold),也被放入Old区
(5) 当Old区被放满的之后,进行完整的垃圾回收,即 FGC
(6) FGC后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现OOM错误
Java应用内存问题分析方法
1.Java内存划分
可粗略划分三类:
1.1 堆内存
存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理
1.2 栈内存
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配(更准确地说是保存了引用的堆内存空间的地址,java中的“指针”)
1.3 永久保存区、方法区(Permanent Generation)
用于存储已被虚拟机加载的类信息、常量、静态变量等
2.Java常见的内存问题表现形式:
2.1 OutOfMemory:内存溢出
2.2 Memory Leak:内存泄露
二者共同点:
(1) 通常最终的状态就会导致OOM错误
(2) 在Java堆或本地内存中都可能发生
二者不同点:
(1) ML是已经分配好的内存或对象,当不再需要,没有得到释放 而OOM则是没有足够的空间来供jvm分配新的内存块
(2) ML的内存曲线总体上是一条斜向上的曲线而OOM不是,反之未必
3.内存溢出类型:
虚拟机栈溢出、本地方法栈溢出、方法区溢出、堆溢出、运行时常量池溢出
异常类型:
(1) java.lang.OutOfMemoryError: Java heap space
堆内存溢出
优化:通过-Xmn(最小值)–Xms(初始值) -Xmx(最大值)参数手动设置 Heap(堆)的大小。
(2) java.lang.OutOfMemoryError: PermGen space
PermGen Space溢出(方法区溢出、运行时常量池溢出)
优化:通过MaxPermSize参数设置PermGen space大小。
(3) java.lang.StackOverflowError
栈溢出(虚拟机栈溢出、本地方法栈溢出)
优化:通过Xss参数调整
Demo代码 :
// Java 堆溢出
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<JavaHeapSpace.OOMObject>();
while (true) {
list.add(new OOMObject());
}
}
static class OOMObject {
}
// 虚拟机栈溢出
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(add());
}
public static int add(){
return add();
}
// 方法区溢出
public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method,
Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invoke(obj, args);
}
});
enhancer.create();
}
}
static class OOMObject {
}
// 运行时常量池溢出
public static void main(String[] args){
// TODO Auto-generated method stub
List<String> list = new ArrayList<String>();
int i = 0;
while (true ){
list.add(String. valueOf(i++).intern());
}
}
// 内存泄露模拟
public static void main(String[] args) {
// TODO Auto-generated method stub
List<int[]> list = new ArrayList<int[]>();
Runtime run = Runtime.getRuntime();
int i=1;
while(true){
int[] arr = new int[1024];
list.add(arr);
if(i++ % 1000 == 0 ){
System.out.print("最大堆内存=" + run.maxMemory() / 1024 / 1024 + "M, ");
System.out.print("已分配内存=" + run.totalMemory() /1024 / 1024 + "M, ");
System.out.print("剩余空间内存=" + run.freeMemory() / 1024 / 1024 + "M, ");
System.out.println("最大可用内存=" + ( run.maxMemory() - run.totalMemory() + run.freeMemory() ) / 1024 / 1024 + "M");
sleep(1000);
}
}
}
public static void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
4.内存泄露现象
heapspace:OutOfMemoryError
开发人员的分析、解决思路
内存对象申请未释放(未及时释放)
线程问题
分别从堆dump和线程dump进行分析:
jmap -dump:format=b,file=heap.dump pid
jstack pid >> thread.dump
5.JAVA DUMP分析工具
IBM HeapAnalyzer:ha456.jar
IBM Thread and Monitor Dump Analyzer:jca457.jar
堆dump分析
占用内存较多代码块
分析代码快上下文
分析占用内存的对象内容
线程dump分析
活跃线程
阻塞线程
等待资源线程
Java应用CPU问题分析方法
1.程序响应慢,CPU高
(1) ThreadDump
jstack pid >> thread.dump
(2) 找到导致cpu高的线程 top -H -p pid
(3) pid 十进制转十六进制
http://tool.oschina.net/hexconvert/
(4) 找到对应的线程UE打开 threaddump文件查找:按十六进制关键字找到对应的线程,把相关的方法找出来,可以精确到代码的行号
2.程序响应慢,CPU不高
一般表现为thread struck在了i/o、db等
实例:
IO阻塞(程序表现为响应慢)
线程状态为“in Object.wait()”,说明正在等待线程池可用资源,由于线程池满导致新的IO请求处于排队等待状态,且发生在:at com.iflytek.diange.data.provider.sendsong.impl.SendSongImpl.getSendSongInfosByUserId(SendSongImpl.java:92)行
3.程序无响应
死锁(程序表现为无响应)
线程状态为“waiting to lock”: 两个线程各持有一个锁,又在等待另一个锁,故造成死锁,且发生在DeadLockTest.java:39行
Java常见问题分析(内存溢出、内存泄露、线程阻塞等)的更多相关文章
- 内存溢出,内存泄漏,CPU溢出区别
内存溢出 out of memory,就是你要的内存空间超过了系统实际分配给你的空间,此时系统相当于没法满足你的需求,就会报内存溢出的错误 内存泄漏是指你向系统申请分配内存进行使用(new),可是使用 ...
- JS高阶---闭包缺点(内存溢出与泄露)
[大纲] [主体] (1)闭包优缺点 .延长局部变量的生命周期2.外部访问函数内部变量 闭包的优点同时也是它的缺点,就是 (2)解决方案 .能不用闭包就不用(很难做到,因为应用较多) .及时释放--- ...
- 【性能诊断】七、并发场景的性能分析(windbg案例,线程阻塞)
简单整理一个测试Demo,抓取dump并验证,步骤如下: Symbol File Path:SRV*C:\Symbols*http://msdl.microsoft.com/download/symb ...
- 详解Java多线程编程中LockSupport类的线程阻塞用法
LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport实际上是调用了Unsafe类里的函数,归结到Unsafe里,只有两个函数: p ...
- Java常见内存溢出异常分析(OutOfMemoryError)
原文转载自:http://my.oschina.net/sunchp/blog/369412 1.背景知识 1).JVM体系结构 2).JVM运行时数据区 JVM内存结构的相关可以参考: http:/ ...
- java命令分析线程死锁以及内存泄漏
一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...
- Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别
前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出 ...
- Java中内存溢出与内存泄露
内存溢出 内存溢出(out of memory),是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给他存了long才能存下的数,就会发 ...
- 什么是内存溢出以及java中内存泄漏5种情况的总结
内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间. 一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出.内存溢出 out of memory ...
随机推荐
- 贪吃蛇—C—基于easyx图形库(下):从画图程序到贪吃蛇【自带穿墙术】
上节我们用方向控制函数写了个小画图程序,它虽然简单好玩,但我们不应该止步于此.革命尚未成功,同志还需努力. 开始撸代码之前,我们先理清一下思路.和前面画图程序不同,贪吃蛇可以有很多节,可以用一个足够大 ...
- [oldboy-django][2深入django]cookies + session
1.1 cookies - 初识cookie a.cookie是保留在浏览器端的键值对 b.服务端可以向客户端写cookie c.客户端每次发送请求,会携带cookie一起发送过去,而且cookie是 ...
- Selenium - WebDriver Advanced Usage
Explicit Waits # Python from selenium import webdriver from selenium.webdriver.common.by import By f ...
- 在线人数统计session管理
下午比较闲(其实今天都很闲),想了一下在线人数统计方面的实现,上网找了下这方面的知识,最初我的想法是,管理session,如果session销毁了就减少,如果登陆用户了就新增一个,但是如果是用户非法退 ...
- 【转】Unity3d的单例及场景间的数据传递
http://blog.csdn.net/zy19940906/article/details/47724387 单例是场景间切换时传递数据的最常见的方式之一,在unity中,很多方法被封装,有时候 ...
- CodeForces Round #515 Div.3 B. Heaters
http://codeforces.com/contest/1066/problem/B Vova's house is an array consisting of nn elements (yea ...
- C++字符串高效查找替换,有空分析分析
void CWebTransfer::Substitute(char *pInput, char *pOutput, char *pSrc, char *pDst) { char *pi, *po, ...
- SQL语句操作符优化
转载地址:http://database.51cto.com/art/200903/112810.htm IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格. ...
- hdu 3045 斜率优化DP
思路:dp[i]=dp[j]+sum[i]-sum[j]-(i-j)*num[j+1]; 然后就是比较斜率. 注意的时这里j+t<=i: #include<iostream> #in ...
- BZOJ4000 [TJOI2015]棋盘 【状压dp + 矩阵优化】
题目链接 BZOJ4000 题解 注意题目中的编号均从\(0\)开始= = \(m\)特别小,考虑状压 设\(f[i][s]\)为第\(i\)行为\(s\)的方案数 每个棋子能攻击的只有本行,上一行, ...