zoukankan      html  css  js  c++  java
  • 系统性能优化

    1. ClassNotFoundException/NoClassDefFoundError/NoSuchMethodException

           参考关于类加载的博文即可,主要关注类加载的方式,类的版本等信息

           https://www.cnblogs.com/baihuitestsoftware/articles/6382733.html

           https://www.cnblogs.com/it-worker365/p/11269635.html

    2.Cpu us消耗高

    linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: 或者top进入后大写的M

    //加标题去标题,第三列倒序排序
    ps -aux | head -1 ; ps aux | grep -v PID | sort -rn -k +3 | head
    //排序
    ps -aux | sort -nr -k3 | head -10

           是否是gc过于频繁,打开gc日志-Xloggc:./gc.log或者通过jstat -gcutil来查看gc和内存的情况,这种根据内存问题来处理

           下面根据top -H -p/ jstack等命令查看是否有死锁,很深的循环或递归,也可能是序列化反序列化之类对象突然变大,计算突然增加   

    /**
     * Created by itworker365 on 5/17/2017.
     */
    public class CpuBusyTest implements Runnable{
        public static void main (String[] args) {
            for (int a = 0; a < 1000; a++) {
                CpuBusyTest test = new CpuBusyTest();
                Thread t = new Thread(test, "t-" + a);
                t.start();
            }
        }
    
        @Override
        public void run() {
            long start = System.currentTimeMillis();
            long k = 0;
            for (long i = 0; i < 2000000000; i++) {
                k = 1 + i;
            }
            System.out.println(Thread.currentThread().getName() + "-----" + (System.currentTimeMillis() - start));
        }

    默认TOP按照进程显示,直接输入TOP看到占用最多的进程,如下,%CPU 99.8

    top -H -p ID查看该进程下的线程情况,如果有一个特别高,可以找到PID,然后转换为16进制,比如2687-》0xA7F,打印进程堆栈 jstack ID在其中找到0xA7F

    我的例子并没有对应,因为中间停掉了,所以意思明白就好,这里打印出jstack信息,找到对应的线程,查看他的状态。

    一个出现死锁的例子

    /**
     * Created by itworker365 on 5/4/2017.
     */
    public class LockTest {
        private static String A = "A";
        private static String B = "B";
        public static void main (String[] args) {
            new LockTest().deadlock();
        }
        private void deadlock () {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (A) {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized (B) {
                            System.out.println("AB");
                        }
                    }
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (B) {
                        synchronized (A) {
                            System.out.println("BA");
                        }
                    }
                }
            });
            t1.start();
            t2.start();
        }
    }

    jstack之后显示deadlock信息

     3. 内存问题

    linux下获取占用内存资源最多的10个进程,可以使用如下命令组合:或者top进入后大写的P

    ps -aux | head -1 ; ps aux | grep -v PID | sort -rn -k +4 | head
    ps -aux | sort -nr -k4 | head -10

        java.lang.OutOfMemoryError: Unable to create new native thread

        用命令统计出当前总java线程数ps -eLf | grep java -c, 查出当前允许的最大句柄数ulimit -u,对比看是否正确,根据需要做出对应的调整,btrace找到哪里创建的线程@OnMethod(clazz="java.lang.Thread", method="start")

        Executors.newCachedThreadPool这种来创建了一个没限制大小的线程池

        java.lang.OutOfMemoryError: Heap Size或GC overhead limit exceeded

        启动时加入-XX:+HeapDumpOnOutOfMemoryError在溢出时dump内存,之后再通过mat等工具再分析,通过btrace来定位代码

        PermGen Space 跟踪class装载情况,用traceClassLoading或者btrace,@OnMethod(clazz="java.lang.ClassLoader", method="defineClass")

        native OOM:Direct ByteBuffer(NIO)-XX:MaxDirectMemorySize=500m来实现当Direct ByteBuffer使用到500m后主动触发fgc来回收

        到底什么算频繁,如果每隔10s或更短时间就来一次cms gc或full gc才算得上

        jmap -dump:format=b,file=***log         jhat ***.log或其他工具分析

        jmap -histo打印加载的对象    jmap -histo:live来触发fgc

    java.lang.OutOfMemoryError: Java heap space堆溢出,大对象多次没被回收,对比回收前后的内存使用量

    StackOverflowError:递归,循环,局部变量过长,参数过多,局部变量作用域外没有释放等

    java.lang.OutOfMemoryError: unable to create new native thread  操作系统没有足够的资源来创建线程,解决方法就是减少线程数量或者-Xss减小单个线程的大小

    java.lang.OutOfMemoryError: PermGen space 类太多,是多个classloader或者太多反射动态加载类导致

    4.文件占用大小排序

    du -s -h /* | sort -nr

    5. Java进程crash或退出

    默认情况下jdk会生成hs_err[pid].log的文件,core dump打开的话也会生成core dump文件

    -XX:+PrintGCDetails

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/log/gcdump

    遇到问题分而治之,隔离问题。将问题隔离到尽可能小的领域中,比如某个特定系统、特定版本、 甚至特定机器中。之后如果是java的问题,还可以继续分析是java应用、容器、或者jdk的问题,最后应该能确定到某个模块的某些代码、一次 commit、一行配置的问题。整个排查问题的过程就是一个从上到下,一步步缩小问题范围的过程。

    状态数据大致可以分为两类:

    一是监控类数据,收集这类数据对于应用的性能影响很小,基本可以忽略不计,所以可以持续收集,比如GC log,应用log等;

    第二类是某些瞬时数据,这些数据要么收集的代价很大,很影响系统性能,要么时效性很高,过了故障点一切可能就都不一样了,所以不能 持续收集,必须迅速的在故障出现点自动采集,比如Heap dump,core dump等。

  • 相关阅读:
    DockerFile构建步骤及命令
    linux安装nginx及常用命令
    docker常用命令
    Docker安装
    获取TrustedInstaller权限
    获取本机公网ip的url地址
    centOS7配置ip
    VS Code配置c语言环境
    Linux l 2.4.20-8 # 溢出
    VMware Destination Host Unreachable
  • 原文地址:https://www.cnblogs.com/it-worker365/p/6867996.html
Copyright © 2011-2022 走看看