zoukankan      html  css  js  c++  java
  • jvm 内存,线程,gc分析

    1.查看 gc的次数,和各个垃圾回收区域的内存比例  jstat 

    jstat -gcutil pid interval(ms) 例子:jstat -gcutil 332 1000

    参数说明如下:
    S0: 新生代中Survivor space 0区已使用空间的百分比

    S1: 新生代中Survivor space 1区已使用空间的百分比
    E: 新生代已使用空间的百分比
    O: 老年代已使用空间的百分比
    P: 永久带已使用空间的百分比


    YGC: 从应用程序启动到当前,发生Yang GC 的次数

    YGCT: 从应用程序启动到当前,Yang GC所用的时间【单位秒】
    FGC: 从应用程序启动到当前,发生Full GC的次数
    FGCT: 从应用程序启动到当前,Full GC所用的时间
    GCT: 从应用程序启动到当前,用于垃圾回收的总时间【单位秒】

    2.内存分析 jmap

     2.1 生成堆栈文件

      -dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名

      jmap -dump:live,format=b,file=/data/dump.hprof 21275

     2.2 查看jvm 当前配置

       jmap -heap 21275

     2.3 打印当前内存中对象的数量排序

           jmap -histo:live 21275 | more

    
    

    3.线程分析  jstack

      jstack [option] PID

    -F : 当正常输出请求不被响应时,强制输出线程堆栈 
    -l : 除堆栈外,显示关于锁的附加信息 
    -m : 如果调用到本地方法的话,可以显示C/C++的堆栈

    4.生成的服务器,一般按下面进行配置。

    8G内存机器:

    • JAVA_OPTS="-Djava.awt.headless=true -server -Xms5000m -Xmx5000m -Xmn2500m -=256M -XX:MaxPermSize=512M -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseParNewGC -verbose:gc -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps -Xloggc:/bankapp/tomcat/logs/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/bankapp/tomcat/logs/heapdump"

    4G内存机器:

    • JAVA_OPTS="-Djava.awt.headless=true -server -Xms2500m -Xmx2500m -Xmn1000m -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseParNewGC -verbose:gc -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps -Xloggc:/bankapp/tomcat/logs/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/bankapp/tomcat/logs/heapdump" 

    注意:jdk1.8的元数据区替代了之前的持久代,而且 元数据区占用linux的内存,不占用jvm内存,这时,如果发现linux内存持续飙高,请注意元数据区。

      另一个jdk1.8的jvm内存,会缓慢增加,而不会,jvm一启动就会占用 Xms Xmx指定的值,慢慢增加到  Xms Xmx指定的值。

    -XX:MinMetaspaceFreeRatio=30 -XX:MaxMetaspaceFreeRatio=60 ?这两个没发现用处。
    -XX:MetaspaceSize=5M -XX:MaxMetaspaceSize=512M  

    5.内存泄漏模拟(jdk1.8)

    5.1堆内存溢出

    好处,生成的对象大约占用1M,最后滚局i的值,可以算出内存的大小。

    import java.util.ArrayList;
    import java.util.List;
     
    public class HeapOomMock {
        public static void main(String[] args) {
            List<byte[]> list = new ArrayList<byte[]>();
            int i = 0;
            boolean flag = true;
            while (flag){
                try {
                    i++;
                    list.add(new byte[1024 * 1024]);//每次增加一个1M大小的数组对象
                }catch (Throwable e){
                    e.printStackTrace();
                    flag = false;
                    System.out.println("count="+i);//记录运行的次数
                }
            }
        }
    }

    5.1栈溢出

    public class StackSOFTest {
    
        int depth = 0;
    
        public void sofMethod(){
            depth ++ ;
            sofMethod();
        }
    
        public static void main(String[] args) {
            StackSOFTest test = null;
            try {
                test = new StackSOFTest();
                test.sofMethod();
            } finally {
                System.out.println("递归次数:"+test.depth);
            }
        }
    }

    5.1元数据区溢出(或者是持久代溢出)

     问题:通过jvisualvm 查看内存gc时,发现元数据区的类载fullgc时没有被卸载?如果有人知道,请多多指教

    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.CallbackFilter;
    import org.springframework.cglib.proxy.Dispatcher;
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;  
    
    public class OOMTest {  
      
        public static void main(String[] args) {  
            System.out.println("Let us do it now.....");  
            for(int i=0;i<100000;i++){  
               Enhancer enhancer = new Enhancer();  
               enhancer.setSuperclass(TestService.class);  
               enhancer.setCallbackTypes(new Class[] {  
                        Dispatcher.class, MethodInterceptor.class });  
               enhancer.setCallbackFilter(new CallbackFilter() {  
                    public int accept(Method method) {  
                        return 1;  
                    }  
                });  
               Class clazz = enhancer.createClass();  
               System.out.println("Time:" + System.currentTimeMillis());   
            }  
        }  
    }  

    5.jvisualvm 

    5.1 jvsiualvm      local java applications cannot be monitored

    echo %TMP%

    查看tmp下面的hsperfdata_username

    我解决的方法是 把username全部大写。

    5.2 单独jvisualvm 安装

    ${jdk}/bin/jvisualvm
    本地jdk中的jvisualvm启动报错

    无法连接 Java VisualVM 插件中心
    1
    解决方式
    舍弃jdk自带jvisualvm,下载独立的。
    http://visualvm.github.io/releases.html
    根据jdk版本选择

    ${jvisualvm}/etc/visualvm.conf更改被注释的visualvm_jdkhome="..."为本机jdk绝对路径

    启动jvisualvm

    工具->插件->设置->插件中心->编辑url
    https://visualvm.github.io/pluginscenters.html
    根据版本选择.gz放到上文url中

  • 相关阅读:
    进程池,线程池,协程,gevent模块,协程实现单线程服务端与多线程客户端通信,IO模型
    线程相关 GIL queue event 死锁与递归锁 信号量l
    生产者消费者模型 线程相关
    进程的开启方式 进程的join方法 进程间的内存隔离 其他相关方法 守护进程 互斥锁
    udp协议 及相关 利用tcp上传文件 socketserver服务
    socket套接字 tcp协议下的粘包处理
    常用模块的完善 random shutil shevle 三流 logging
    day 29 元类
    Django入门
    MySQL多表查询
  • 原文地址:https://www.cnblogs.com/z-test/p/10196819.html
Copyright © 2011-2022 走看看