1. 线程运行诊断
CPU占用过多
定位:
- 用top定位哪个进程对cpu占用过高
- ps H -eo pid, tid, %cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)
- jstack进程id:可以根据线程id找到有问题的线程,进一步定位到问题代码的源码行号
2. 本地方法栈
- Native Method Stacks:本地方法栈
- 解释:本地方法就是那些不是由Java代码编写的方法,因为Java代码有限制,有些情况下不能和操作系统底层进行交互,所以就需要由C 或 C++ 编写的本地方法来与操作系统打交道,所以本地方法执行时候所使用的就是本地方法栈
- 作用:为本地方法的运行提供内存空间
3. 堆(Heap)
- 通过new关键字,创建对象都会使用堆内存
- 特点:
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制
4. 堆内存溢出
- OutOfMemoryError:Java heap space
- 不断产生对象,且对象被使用(不会被回收),对象堆积会造成堆内存溢出
5. 堆内存诊断
- jps工具
- 查看当前系统中有哪些Java进程
- jmap工具
- 查看堆内存占用情况 jmap -heap 进程id(查询当前时刻,不能连续监测)
- jconsole工具
- 图形界面,多动能的监测工具,可以连续监测
6. 方法区(Method Area)
- 所有Java虚拟机线程共享的区域
- 存储了和类相关的信息
- 方法区在虚拟机启动时被创建
7. 方法区内存溢出
- 1.8之前会导致永久代内存溢出
java.lang.OutOfMemoryError:PermGen space
- XX:MaxPermSize=8m
- 1.8之后会导致元空间内存溢
| | |
|–|--|
| | |
出
演示元空间内存溢出 java.lang.OutOfMemoryError:Metaspace
- XX:MaxMetaspaceSize=8m
8. 运行时常量池
- 常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量(字符串、基本整数、布尔类型等)等信息
- 运行时常量池,常量池是*.class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
9. StringTable特性
- 常量池中的字符串仅是符号,第一次用到时才变为对象
- 利用串池的机制,来避免重复创建字符串对象
- 字符串变量拼接的原理是StringBuilder(1.8)
- 字符串常量拼接的原理是编译器优化
- 可以使用intern方法,主动将串池中还没有的字符串对象放入串池
- 1.8将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池,会把串池中的对象返回
- 1.6将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池,会把串池中的对象返回