LINUX、JAVA垃圾回收和多线程

本文探讨了Linux系统监控与性能诊断,包括CPU、内存、网络和硬盘I/O的常用命令,以及如何处理CPU过高问题。接着深入讲解了Java的垃圾回收机制,如可达性分析、垃圾回收算法和收集器。同时,文章还介绍了Java多线程的原理,如线程状态、并发模型以及同步机制。最后,涉及了线程安全、锁的实现以及并发工具的使用。
摘要由CSDN通过智能技术生成

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因此
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值