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 ...
随机推荐
- ls 的顺序与倒序排列
linux 中文件夹的文件按照时间倒序或者升序排列 1,按照时间升序 ls -lrt -l use a long listing format 以长列表方式显示(详细信息方式) -t sort by ...
- [转]Docker容器内不能联网的6种解决方案
注: 下面的方法是在容器内能ping通公网IP的解决方案,如果连公网IP都ping不通,那主机可能也上不了网(尝试ping 8.8.8.8) 1.使用--net:host选项 sudo docker ...
- spring+xml集成测试(准备数据和验证项的外部文件化)
Spring的集成测试 单位测试和集成测试,我想大家都做过,一般情况下,一般逻辑且不需要操作数据库的情况比较适合于单位测试了.而对于一个数据库应用来说,集成测试可能比单元测试更重要,你可以想象,一个互 ...
- [HAOI2018][bzoj5306] 染色 [容斥原理+NTT]
题面 传送门 思路 这道题的核心在于"恰好有$k$种颜色占了恰好$s$个格子" 这些"恰好",引导我们去思考,怎么求出总的方案数呢? 分开考虑 考虑把恰好有$s ...
- Brain Powerd计划
Brain Powerd这片子没有高清的版本,只有DVD..(我手上只有个DVDRip,X2字幕组的)同时字幕质量也不行. 开个坑用waifu2x压个好看一点(用DVDRip)的,码率大概是3.3M ...
- flake8(代码规范利器)
flake8(代码规范利器) 概述 flake8是下面三个工具的封装: 1)PyFlakes 2)Pep8 3)NedBatchelder’s McCabe script Flake8的下载地址:ht ...
- 开启dns服务时,/etc/init.d/named start 卡住了的解决办法。
在命令行输入 rndc-confgen -r /dev/urandom -a 再次开启服务 /etc/init.d/named start ok
- iOS 关于请求参数在cookie里面
一.首先了解一下什么cookie cookie是在客户端存储服务器状态的一种机制.web服务器可以通过set-cookie或者set-cookie2 HTTP头部设置cookie. Cookie可以分 ...
- JAVA神操作--使用Arthas线上热更新实战
热更不规范,同事两行泪 背景 C君是一个javaer,最近在开发用户登出接口的时候,不小心把接口参数拼错了 正确的是: /api/v1/user/logout?referrer=www.javaer. ...
- Gate Of Babylon(bzoj 1272)
Description Input Output Sample Input Sample Output 12 HINT /* 容斥+lucas+乘法逆元 首先,看到有限制的只有15个,因此可以用容斥原 ...