问Linux命令的时候,不是列出这些命令,而是说当时在解决什么问题时用的这个命令。
OOM发生场景,反映到JVM内部是怎么样的
SOF(java.lang.StackOverflowError):
while导致方法栈溢出、递归调用太深导致栈溢出。
函数内的数组过大,导致栈溢出。
OOM(java.lang.OutOfMemoryError):
1.Java Heap space:
堆内存不足以存放新创建出的对象、堆内存使用量达到最大内存限制、内存泄露逐渐堆积。比如缓存在内存中存储,我们提前对数据库中的用户进行全量存储,为了方便查找放在Map中。但现在有这么一个需求,需要下拉立即显示模糊的用户名。那么每一级的key都会对应很多用户名,这些都需要一个单独的Map存储,就可能撑爆内存发生OOM。所以我们可以使用key+Set,过滤掉每一级多余的用户名,减少对象的数量。
解决:增大堆内存空间
2.GC overhead limit exceeded:
Executors.newFixedThreadPool提供的线程池默认的任务队列无界,所以队列可能快速挤压,撑爆内存导致OOM.
3.Direct buffer memory(直接内存溢出):
NIO的ByteBuffer.allocateDirect(capability)方法:使用JVM堆内存外的本地内存进行数据拷贝。没有使用JVM所以不触发GC,对象不被回收,时间久了本地内存就会被用完,就会出现OutOfMemoryError。
解决:手动释放buffer、增大本地内存
4.unable to create new native thread:
Executors.newCachedThreadPool提供的线程池,它的最大线程数是没有上限的,而它默认使用SynchronousQueue无存储空间的阻塞队列,也就意味着只要有请求到来就需要有线程来执行,即会无限创建大量的线程导致OOM。
解决:降低线程数、修改服务器线程上限配置
5.Metaspace(元空间):
就是方法区呀,存放类信息、常量池、静态变量。元空间满了就报此异常
内存泄漏和内存溢出
内存泄漏是指不再使用的对象没有被及时回收,持续占用内存而造成的空间浪费。
new subString()会调用new String(),利用到原来的字符串。但如果subString只使用了String中的一小段,而String字符串不再被使用,此时String字符串被subString引用而无法回收,造成内存泄露 内存溢出是发生OOM,垃圾回收的速度跟不上场景对象的速度。
JVM参数与命令
-xms、-xmx、-xss分别代表了什么?为什么要有这些参数
-Xms:指定程序启动时申请的内存空间大小,也就是创建进程时需要的Java堆大小。当初始内存不够时会自动扩容。
-Xmx:指定程序运行时最大可占用的内存大小。
-Xss:指定每个线程的堆栈大小(堆内存设置过大:寻址开销变大,增加JVM的负载。
64G内存的机器,JVM参数如何配置:
JVM的初始-xms默认是物理内存的1/64,-xmx默认是物理内存的1/4.当默认空余堆内存小于40%时,JVM会增大堆直到-xmx;当空余堆内存大于70%时,JVM会减少堆直到-xms。所以服务器一般设置-xms与-xmx相等,避免每次GC后都要调整堆。32位系统的可控内存空间有4G,所以限制为2G-3G。
查看JVM参数:ps得到进程id,jmap -heap pid查询到JVM配置信息(包括垃圾收集器类型)
JVM有哪些参数可以设置
①执行时:-Xms指定堆初始大小、-Xms指定堆最大值、-Xss每个线程的堆栈大小
②-XX:+Use...GC:指定使用的GC类型。
③开启G1:-XX:UseG1GC
④设置GC最大停顿时间(G1的预期停顿时间):-XX:MaxGCPauseMills
⑤直接内存大小:-XX:MaxDirectMemorySize
⑥打印GC日志:见下面
Java排查性能问题的参数
①top:实时显示各个进程的CPU占用率、内存使用率等资源占用情况。
②top -Hp pid:查看具体线程的CPU占用率。
③vmstat:可以指定采样周期和次数的监测工具,可以用来查看上下文切换次数
④jstat:查看堆内存信息和GC信息。jstat -gc显示GC相关的堆信息、jstat -gcutil显示GC信息。它会打印各个元区使用量和GC次数。
⑤jstack:查看线程的堆栈信息。
⑥jmap:输出堆内存的对象信息
查看GC信息:
①jstat -gcutil pid {时间间隔}:显示各个元区的占用百分百与GC次数。
②-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/log/heapTest.log:将运行时的GC日志dump下来。
排查问题
CPU 100%处理过程:
①通过top命令找到占用CPU最高的进程pid
②通过top -Hp pid找到进程中占用CPU过高的线程tid
③通过jstack pid | grep tid {-A 30} 得到线程堆栈信息,根据堆栈信息就可以定位到项目中的问题了。
排查OOM内存溢出:
①配置JVM启动参数-XX:HeapDumpOnOutOfMemoryError与-XX:HeapDumpPath,JVM发生OOM时就会自动生成dump日志
②使用 jmap -dump:format=b , file=D:\test\heap.hprof 6956导出dump日志(进程号:netstat -ano | find “8080” 查看当前应用程序使用的进程号。)
③可以使用JDK自带的jvisualvm导入dump快照,进行查看。
排查内存泄露
内存泄露有可能会引发频繁的full GC,所以可以用jstat -gcutil查看GC相关信息。
内存泄露可能会引发内存溢出,所以见上。
Linux命令
查看所有正在运行的Java程序:ps -aux | grep java
awk:awk '{print 0}' (0整行,$1第一个字段)
查看倒数第二列,查看第10-20行
tail -n 2
head -20 a.txt | tail -11
head -n 100 显示前100行,tail -n 100 从100行开始显示后面的。
top:实时显示各个进程的资源占用情况,如CPU利用率、cpu平均负载等。
cpu使用率:单位时间内,CPU的繁忙情况
cpu平均负载:单位时间内,系统中处于可运行状态、休眠但不可中断状态的平均进程数。
如何查看端口:netstat -anp
chmod:r4代表可读,w2代表可写,x1代表可执行
Linux查找某个目录下匹配的文件名
find . -name 'xxx'
grep -rnl 'xxx' 递归查找、不显示行号、只输出文件名 Linux查找某个目录下含有某字符串的文件名 find .|xargs grep -ri 'xxx' -l ,-i不区分大小写、-l只输出文件名
查找文件中含有xxx字符串的行
sed -n '/xxx/p' a.txt
more分页查询(空格向下、ctrl+B向上一屏)
- (工具网址:chrome-error://chromewebdata)
- 查找文件
-
- -i:搜索时忽略大小写
- Find /home -name "*log":查找home目录及其子目录下以“log”结尾的文件。
-
- | xargs grep “xxx” 判断日志中是否有内容xxx,返回true false
-
- type f是文件、-type d是目录
- Find . -iname a.txt -o -iname b.txt:忽略大小写,查找当前目录下的a.txt和b.txt
- Find . -maxdepth n -type f:指定搜索深度打印出当前目录的文件。
- Find . - type -name “*.swp” -delete:删除当前目录下的所有swap文件。
- 文本搜索grep,用于过滤:
-
- grep附加的常用参数:
-
- -o :输出匹配的文本行
- -v:输出不匹配的文本行
- -c:统计次数
- -n:附带输出匹配的行号
- -R:递归多级子目录
- -e: “xxx” -e ”xxx” or的作用
- 其中’xxx’可以是正则表达式
-
- [gd] == g??d
- g..d==g??d
- ^xxx:以xxx开头
- xxx$:以xxx结尾
- 查找带where条件的sql语句:
- Tail查看文件
-
- Tail -n 10 文件路径:查看文件的最后10行(加上-f 是查看实时日志)
- Tail -n +10 文件路径:查看文件的最前10行之后的所有日志
- Head -n 10 文件路径:查看文件的最前10行
- awk
-
- | awk ‘/.../‘:可以用正则表达式指定条件,可以用循环
- 正则表达式:%s、print 2
- 场景1:查看某关键字附件的日志
-
- 得到关键字处于的行号:Cat -n aaa.log | grep “你好”
- 查看关键字的前后10行:cat -n aaa.log | tail +10 | head -n 20
- 得到关键字行号后,根据基本tail命令查看行号前后的日志
- 场景2:按日期时间查找日志
-
- Sed -n ‘/日期/p’ aaa.log
- 场景3:前面得到的日志文件过多?
-
- | less:分页(b是向前翻一页,空格是向后翻一页)
-
xxx.txt:输出到文件中
- 正则:
-
- 正则方式查找.txt和pdf:find . -regex “.*(.txt|.pdf)$”