简单的说就是内存中已经不再被使用到的空间就是垃圾
引用计数法
Java中,引用和对象是有关联的。如果要操作对象则必须用引用进行
因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,给对象中添加一个引用计数器,
每当有一个地方引用它,计数器值加1
每当有一个引用失效时,计数器值减1。
任何时刻计数器值为零的对象就是不可能再被使用的,那么这个对象就是可回收对象
那为什么主流的Java虚拟机里面都没有选用这种算法呢?其中最主要的原因是它很难解决对象之间相互循环引用的问题
枚举根节点做可达性分析(根搜索路径)
demo
java 可以做GCRoots的对象
-Xcomp 第一次使用就编译成本地代码
-Xmixed 混合模式
公式
-XX:+或者- 某个属性值
+表示开启 -表示关闭
是否打印GC收集细节
-XX:+PrintGCDetails
-XX:-PrintGCDetails
是否使用串行垃圾收集器
-XX:-UseSerialGC
-XX:+UseSerialGC
公式
-XX:属性key=属性值value
-XX:MetaspaceSize=128m
-XX:MaxTenuringThreshold=15
公式
jinfo -flag 配置项 进程编号
两个经典参数:-Xms和-Xmx
-Xms <===>等价于 -XX:InitialHeapSize
-Xmx <====>等价于-XX:MaxHeapSize
-XX:+PrintFlagsInitial
查看初始默认值
公式
java -XX:+PrintFlagsInitial -version
java -XX:+PrintFlagsInitial
初始大小内存,默认为物理内存1/64
等价于-XX:InitialHeapSize
最大分配内存,默认为物理内存1/4
等价于-XX:MaxHeapSize
设置单个线程的大小,一般默认为512K~1024K
等价于-XX:ThreadStackSize
设置年轻代大小
设置元空间大小
元空间的本质和永久代类似,都是对JVM规范中方法区的实现,不过元空间与永久代之间最大的区别在于;元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,源空间的大小仅受本地内存限制。
-Xms10m -Xmx10m -XX:MetaspaceSize=1024m -XX:+PrintFlagsFinal
输出详细GC收集日志信息
递归调用 栈的大小默认为512K~1024K
程序在垃圾回收上花费了98%的时间,却收集不回2%的空间,通常这样的异常伴随着CPU的冲高
-XX:+PrintFlagsInitial命令查看本机的初始化参数,-XX:MetaspaceSize为21810376B(约20M)
GC算法(引用计数/复制/标清/标整)是内存回收的方法论,垃圾收集器就是算法落地实现
因为目前为止还没有完美的收集器出现,更加没有万能的收集器,只是针对具体应用最合适的收集器,进行分代收集
它为单线程环境设计并且只使用一个线程进行垃圾回收,会暂停所有的用户线程。所以不适合服务器环境
并行垃圾回收器(Parallel)
多个垃圾回收线程并行工作,此时用户线程是暂停的,适用于科学计算/大数据处理等弱交互场景
并发垃圾回收器(CMS)
用户线程和垃圾收集线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程
互联网公司多用它,适用于对响应时间有要求的场景
G1垃圾回收器
G1垃圾回收器将堆内存分割成不同的区域然后并发的对其进行垃圾回收
java -XX:+PrintCommandLineFlags -version
串行GC(Serial)/(Serial Coping)
并行GC(ParNew)
并行回收GC(Parallel)/(Parallel Scavenge)
串行回收GC(Serial Old)/(Serial MSC)
并行GC(Parallel Old)/(Parallel MSC)
并发标记清除GC(CMS)
4个过程
初始标记(CMS initial mark)
并发标记(CMS concurrent mark)和用户线程一起
重新标记(CMS remark)
并发清除(CMS concurrent sweep)和用户线程一起
优点:
并发收集低停顿
缺点:
最大好处是化整为零,避免全内存扫描,只需要按照区域来进行扫描即可
uptime,系统性能命令的精简版
查看所有CPU核信息
mpstat -P ALL 2
每个进程使用cpu的用量分解信息
pidstat -u 1 -p 进程编号
pidstat -p 进程号 -r 采样间隔秒数
pidstat -d 采样间隔秒数 -p 进程号
结合Linux和JDK命令一块分析
ps -ef|grep java|grep -v grep
ps -mp 进程 -o THREAD,tid,time
-m 显示所有线程
-p pid进程使用cpu的时间
-o 该参数后是用户自定义格式
4. 将需要的线程ID转换为16进制格式(英文小写格式)
windows系统计算器可以自动进行进制转化
printf “%x\n” 有问题的线程ID
A60 前60行