资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

JVM调优篇

Java 更新时间: 发布时间: 计算机考试归档 最新发布

JVM调优篇

目录

  • JVM理解
    • JVM生命周期
    • JVM架构图
    • 类的加器分类
  • 1:字节码篇
    • 1.0:字节码工具
  • 2:类的加载篇
    • 2.0:api
    • 2.1:启动类加载器(Bootstrap ClassLoader)
    • 2.2:扩展类加载器(Extension ClassLoader)
    • 2.3:系统类加载器(AppClassLoader)
    • 2.4:自定义类加载器
  • 3:运行时内存篇
    • 3.0:堆内存大小参数
    • 3.1:内存溢出dump文件分析
  • 4:垃圾回收篇
    • 4.1:垃圾判别算法
  • 5:JVM监控及诊断工具篇
    • 5.0: 命令行篇

JVM理解

JVM生命周期

JVM架构图


类的加器分类


1:字节码篇

1.0:字节码工具

1:官方查看字节码工具: javap

2:IDEA查看字节码工具

  1. IDEA下载jclasslib插件,编译java文件
  2. 点击View, 找到 Show Bytecode With Jclasslib

2:类的加载篇

2.0:api

方法描述
getClassLoader()获取加载器
getParent()获取父类加载器
   @Test    public void test1(){        // 对于自定义类,使用系统类加载器进行加载        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();           System.out.println(classLoader);        //调用系统类加载器的getParent();获取扩展类加载器        ClassLoader classLoader1 = classLoader.getParent();        System.out.println(classLoader1);        //调用扩展加载器的getParent():无法获取引导类加载器        // 引导类加载器主要负责加载java的核心类库,无法加载自定义类的。        ClassLoader classLoader2 = classLoader1.getParent();        System.out.println(classLoader2);        //String的加载类是类加载器。        ClassLoader classLoader3 = String.class.getClassLoader();        System.out.println(classLoader3);    }

2.1:启动类加载器(Bootstrap ClassLoader)

package chapter04.java; import java.net.URL; public class ClassLoaderTest {    public static void main(String[] args) {        System.out.println("**********启动类加载器**************");        // 获取 BootstrapClassLoader 能够加载的 api 的路径        URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();        for (URL element : urLs) {            System.out.println(element.toExternalForm());        }        // 从上面的路径中随意选择一个类,来看看他的类加载器是什么:引导类加载器        ClassLoader classLoader = java.security.Provider.class.getClassLoader();        System.out.println(classLoader);// null  引导类加载器是获取不到的    }}

执行结果

**********启动类加载器**************file:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/resources.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/rt.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/sunrsasign.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/jsse.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/jce.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/charsets.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/lib/jfr.jarfile:/D:/ProgramFiles/Java/jdk1.8.0_251/jre/classesnull

2.2:扩展类加载器(Extension ClassLoader)

package chapter04.java; import java.net.URL; public class ClassLoaderTest {    public static void main(String[] args) {        System.out.println("***********扩展类加载器加载路径*************");        String extDirs = System.getProperty("java.ext.dirs");        for (String path : extDirs.split(";")) {            System.out.println(path);        }         // 从上面的路径中随意选择一个类,来看看他的类加载器是什么:扩展类加载器        ClassLoader classLoader1 = sun.security.ec.CurveDB.class.getClassLoader();        System.out.println(classLoader1); // sun.misc.Launcher$ExtClassLoader@1540e19d    }}

执行结果

***********扩展类加载器加载路径*************D:ProgramFilesJavajdk1.8.0_251jrelibextC:WINDOWSSunJavalibextsun.misc.Launcher$ExtClassLoader@5cad8086 

2.3:系统类加载器(AppClassLoader)

通过ClassLoader的getSystemClassLoader() 方法可以获取到该类加载器

2.4:自定义类加载器

  1. 继承ClassLoader类
  2. 重写findclass()方法;
public class MyClassLoader extends ClassLoader {    private String path;     public MyClassLoader(String path) {        this.path = path;    }     public MyClassLoader(String path, ClassLoader parentClassLoader) {        super(parentClassLoader);        this.path = path;    }         @Override    protected Class findClass(String name) throws ClassNotFoundException {        BufferedInputStream bis = null;        ByteArrayOutputStream baos = null;        try {            bis = new BufferedInputStream(new FileInputStream(path + name + ".class"));            baos = new ByteArrayOutputStream();            int len;            byte[] data = new byte[1024];            while ((len = bis.read(data)) != -1) {                baos.write(data, 0, len);            }            //获取内存中的完整的字节数组的数据            byte[] classByteArray = baos.toByteArray();            //将字节数组转换为Class的实例            return defineClass(null, classByteArray, 0, classByteArray.length);        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (null != baos) {                    baos.close();                }            } catch (IOException e) {                e.printStackTrace();            }            try {                if (null != bis) {                    bis.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return null;    }}

测试:

public class MyClassLoaderTest {    public static void main(String[] args) throws ClassNotFoundException {        MyClassLoader myClassLoader = new MyClassLoader("d:/");        Class aClass = myClassLoader.loadClass("Demo");        System.out.println("加载此类的类加载器为: " + aClass.getClassLoader());        System.out.println("加载此类的类加载器的父类加载器为: " + aClass.getClassLoader().getParent().getClass().getName());    }}

运行结果:

加载此类的类加载器为: com.wsh.MyClassLoader@2f2c9b19加载此类的类加载器的父类加载器为: sun.misc.Launcher$AppClassLoader

3:运行时内存篇

3.0:堆内存大小参数

  1. -Xms:初始堆大小
  2. -Xmx:最大堆大小
  3. -XX:NewRatio:设置新生代和老年代的比值。如:为3,表示年轻代与老年代比值为1:3
  4. -XX:PrintGCDetails:查看程序运行GC的运行情况

3.1:内存溢出dump文件分析

4:垃圾回收篇

4.1:垃圾判别算法

  1. 引用技术算法:

给对象添加一个引用计数器,每当对象被引用了,计数器加1,当引用失效之后,计数器减1,当值为0时就是可回收的对象。该方法存在一个循环引用的问题,如下代码

public class Test{	public static void mian(String[] args){		ObjectA A=new ObjectA();		ObjectB B=new ObjectB();		A=B;		B=A;		A=null;		B=null;	}}
在这段代码中,代码执行到B=A该语句时,ObjectA和ObjectB的引用计数均为2,而执行代码结束之后,A和B都置为null,两个对象的计数均减1,但是还存在着A和B之间的相互引用,此时ObjectA和ObjectB的引用计数仍为1,而A和B两个实例又早已不用,终将会进入一种循环状态,导致无法被当成垃圾进行回收。
  1. 可达性分析算法

判断对象与GCRoot是否有引用链,即是否可达,如果对象到GCRoot没有任何引用链,则对象是不可用的,可被当成垃圾进行回收;如果是可达的,则对象不可回收。

如A与GCRoot有相连,B与A相连,C与B相连,这几个对象都是与GCRoot有连接,都是可达对象

而出现一个D不与上述某一对象连接,或者是链接了一个不与GCRoot有连接的对象,则它与GCRoot不可达,是可回收的对象

5:JVM监控及诊断工具篇

5.0: 命令行篇

  1. jps:查看正在运行的java进程
  2. jmap:dump内存文件
    例如:jmap -dump:live,format=b,file=zhang.hprof pid
转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/1095066.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【JVM调优篇】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2