文章目录
- Linux常见命令
- JAVA垃圾回收
- JAVA多线程
- 网络通信
Linux常见命令
生产服务器变慢,该怎样诊断和定位?—根据cpu和内存查看底层代码来定位
top
查看消耗系统资源最多的进程,显示具体哪一个cpu负载情况、内存、 load average(负载均衡)、显示1分、5分、15分 (3值相加/3>=60%)表示系统负担过重
系统命令精简版:uptime也可以看到上述情况
CPU—vmstat
vmstat -n 2 3
查看所有CPU核信息 mpstat
2表示每2s打印一次
idle表示cpu空间率,越高越好
某个进程使用cpu用量分解信息:pidstat
先查看消耗内存最多的进程PID:ps
对用户u每秒采样1次
内存 free -m
GB单位
或者使用:pidstat -P 进程号 -r 采样间隔
网络IO
ifstat,此命令需要先下载,使用wget、tar、make、make Install
硬盘 df
df -h
磁IO:iostat -xdk 2 3
util:1s内有百分之几的时间用于IO
或者使用pidstat来查看磁盘: pidstat -d 2 -p 进程号
如果CPU占用过高怎么办?
1:top命令找消耗资源最多的进程,记住pid
2:查看此进程详细信息:ps -ef | grep pid 或者 jps -l
3:定位到cpu使用最高的线程: ps -mp 进程id -o THREAD,tid,time
4: 将线程转换为16进制tid,printf("%x%n",pid);
5: 通过运行轨迹定位到具体代码:
jstack 进程id | grep tid -A60
JAVA垃圾回收
堆内的对象没有栈中的变量去引用时就会成为一个垃圾对象。垃圾回收发生在堆中。
查看默认垃圾收集器
如何定位一个垃圾对象?
- 引用计数法:
每个对象有一个引用计数器,每当栈中变量对其有一个引用,这个计数器就加一,引用失效计数器就减一,当栈中没有变量进行引用时就是计数器为0时这个对象就成为了垃圾对象。但是引用计数法无法解决对象相互循环引用但栈中没有变量对这两个对象进行引用,这样引用计数器无法通知gc去进行回收的问题。
class ReferenceCountingGC(
private static Object obj=new Object();
Object instance=null;
public static void main(String[] args){
ReferenceCountingGC objA=new ReferenceCountingGC();
ReferenceCountingGC objB=new ReferenceCountingGC();
objA.instance=objB;//堆内对象互相引用
objB.instance=objA;//堆内对象互相引用
objA=null;//栈中变量引用失效
objB=null;//栈中变量引用失效
}
)
- 可达性分析算法
按照GCroot对象做为根节点,开始向下搜索引用的对象,找到的对象都标记为非垃圾对象,没有标记的为垃圾对象。
GCroot对象指线程栈的本地变量,静态变量,本地方法栈的变量
由于对象循环引用没有根对象引用,属于垃圾对象,解决了对象之间互相引用的问题。
判断了垃圾对象就要进行垃圾回收了,
垃圾回收算法:3个
- 复制算法 --年轻代
将空间复制2份,每次使用一半,回收时将存活对象复制到另一半,对当前这一半全部清除,浪费空间,不产生碎片
-
MpSweep标记清除算法–老年代
将垃圾内存标记为可回收,再对其回收
未被使用的空间不连续,产生碎片 -
MapCompating标记压缩算法—老年代
与标记清除算法上标记阶段相同,让存活对象像一端移动,端外内存直接清除。不产生空间碎片,效率偏低
java垃圾收集器:首先要理解什么是STW?
- STW指在垃圾回收算法执行中,冻结JVM内存状态。java所有线程都停止执行,除了GC线程。本地方法可以执行但不与内存交互。GC算法优化目的就是为了减少STW的时间。JVM调优的重点。
jdk1.8之前用分代模型 使用ps+po为默认垃圾收集器,之后用分区模型 G1
分代:
新对象存储在eden区,eden区满了之后执行引擎按照根可达性算法将标记的非垃圾对象通过复制算法放入Survivor区,每移动一次经过一次GC,年龄+1,当年龄为15,放入老年代,老年代满了之后程序产生stw时间很长,使用标记整理算法来清除垃圾。
java垃圾回收器有:
- serial:串行 ,需要GC时暂停所有用户线程,GC完后再继续用户线程。只使用一个线程进行垃圾回收。程序–>GC–>程序
不适合服务器环境
- Paralleo:多个垃圾收集线程并行工作,用户线程是暂停的。节省了程序暂停的时间。duoCPU架构下性能比serial高很多。ps+po为默认垃圾收集器,
- CMS(Concurrent Mark Sweep):用户线程和GC并发进行,不需要停顿用户线程,解决STW时间过长的问题。整个GC分为4个阶段:
1:初始标记:对根对象引用的第一个对象进行标记。STW
2:并发标记:与应用程序一起并发继续标记,
3:重新标记:对并发执行阶段运行时变化的对象重新标记。 STW
4:并发清除:并行,应用程序继续执行且对垃圾进行清除,此时应用程序产生的垃圾为浮动垃圾。留到下一次GC清除。
- G1:将堆内存分割成不同的区域,每个区都会从新生代到年老代进行转化。GC分为4各阶段:
1、初始标记:标记跟GCroot关联的对象 STW
2、并发标记Rigion:Rset是Region里面的一个数据结构,记录与当前Rigion有引用关系的Rigion(如果当前区为Old,记录从Eden到S区再到Old区的Rigion),
3、并发标记对象:遍历范围不是整个OLD区,而是遍历第二步标记的Rigion。
4、重新标记:将并发标记中产生变化的对象重新标记
5、垃圾清理:采用复制算法,将整个Rigion中的对象拷贝到新的Rigion中,选择垃圾多的Rigion进行清理。
避免全内存扫描,只需要区域扫描,并发的进行垃圾回收,可以设置垃圾回收时间,小区域范围收集+连续的内存空间不会产生内存碎片
整体采用标记整理,局部复制算法
CMS核心三色标记、错标、漏标
黑色:自己与成员变量,自己引用的对象都标记完
灰色:自己标记完,成员变量没有标记完
白色:自己没有标记完
- 错标:
- 漏标:A自己与成员变量已经标记完成,A引用B,B自己标记完但成员变量还没有标记,B引用C,C因此