JVM

在这里插入图片描述
在这里插入图片描述
反编译:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以获取该类的所有的方法,但是不能获取继承的或者所实现的接口的方法。
在这里插入图片描述
只能获取该类的public方法,但是能够获取继承的public方法和所实现的接口的方法。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
自定义classLoader

package com.interview.javabasic.reflect;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {
    private String path;
    private String classLoaderName;

    public MyClassLoader(String path, String classLoaderName) {
        this.path = path;
        this.classLoaderName = classLoaderName;
    }

    //用于寻找类文件
    @Override
    public Class findClass(String name) {
        byte[] b = loadClassData(name);
        return defineClass(name, b, 0, b.length);
    }

    //用于加载类文件
    private byte[] loadClassData(String name) {
        name = path + name + ".class";
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = new FileInputStream(new File(name));
            out = new ByteArrayOutputStream();
            int i = 0;
            while ((i = in.read()) != -1) {
                out.write(i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return out.toByteArray();
    }
}
package com.interview.javabasic.reflect;

public class ClassLoaderChecker {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        MyClassLoader m = new MyClassLoader("/Users/baidu/Desktop/", "myClassLoader");
        Class c = m.loadClass("Wali");
        System.out.println(c.getClassLoader());
        System.out.println(c.getClassLoader().getParent());
        System.out.println(c.getClassLoader().getParent().getParent());
        System.out.println(c.getClassLoader().getParent().getParent().getParent());
        c.newInstance();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.interview.javabasic.reflect;

public class ClassLoaderChecker {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        MyClassLoader m = new MyClassLoader("/Users/baidu/Desktop/", "myClassLoader");
        Class c = m.loadClass("Wali");
        System.out.println(c.getClassLoader());
        System.out.println(c.getClassLoader().getParent());
        System.out.println(c.getClassLoader().getParent().getParent());
        System.out.println(c.getClassLoader().getParent().getParent().getParent());
        c.newInstance();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.interview.javabasic.reflect;

public class Robot {
    private String name;
    public void sayHi(String helloSentence){
        System.out.println(helloSentence + " " + name);
    }
    private String throwHello(String tag){
        return "Hello " + tag;
    }
    static {
        System.out.println("Hello Robot");
    }
}
package com.interview.javabasic.reflect;

public class LoadDifference {
    public static void main(String[] args) throws ClassNotFoundException {
        //ClassLoader cl = Robot.class.getClassLoader();//无反应
        //Class r = Class.forName("com.interview.javabasic.reflect.Robot");//输出静态语句,证明执行了初始化该类
    }
}
package com.interview.javabasic.reflect;

加载数据库驱动的类:
public class LoadDifference {
    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.mysql.jdbc.Driver");
    }
}

在这里插入图片描述

loadClass:
Spring ioc加载xml配置文件中的bean,使用懒加载加快初始化速度,loadClass不需要执行验证和链接的步骤。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
反编译:
在这里插入图片描述
在这里插入图片描述
Istore弹出栈,iload压入栈。
在这里插入图片描述
全是正数时:
在这里插入图片描述

package com.interview.javabasic.jvm.model;

public class Fibonacci {
    //F(0)=0,F(1)=1,当n>=2的时候,F(n) = F(n-1) + F(n-2),
    //F(2)=F(1) + F(0) = 1, F(3) = F(2) + F(1) = 1+1 = 2
    //F(0)-F(N) 依次为 0,1,1,2,3,5,8,13,21,34...
    public static int fibonacci(int n){
        if(n == 0) {return 0;}
        if(n == 1) {return 1;}
        return fibonacci(n - 1) + fibonacci(n - 2);
    }

    public static void main(String[] args) {
        System.out.println(fibonacci(1000000));
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一般讲-Xms和-Xmx设置为一样的值,防止内存扩充时内存抖动。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.interview.javabasic.jvm.model;

import java.util.Random;

public class PermGenErrTest {
    public static void main(String[] args) {
        for(int i=0; i <= 1000; i++){
            //将返回的随机字符串添加到字符串常量池中
            getRandomString(1000000).intern();
        }
        System.out.println("Mission Complete!");
    }

    //返回指定长度的随机字符串
    private static String getRandomString(int length) {
        //字符串源
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for ( int i = 0; i < length; i++){
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }
}

Jdk6:
永久代大小:
在这里插入图片描述
在这里插入图片描述
Jdk7:
在这里插入图片描述
Jdk8:
在这里插入图片描述
在这里插入图片描述
Jdk8:

package com.interview.javabasic.jvm.model;

public class InternDifference {
    public static void main(String[] args) {
        String s = new String("a");
        s.intern();
        String s2 = "a";
        System.out.println(s == s2);

        String s3 = new String("a") + new String("a");
        s3.intern();
        String s4 = "aa";
        System.out.println(s3 == s4);
    }
}

在这里插入图片描述
Jdk6:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编译后,在字符串常量池中存在“a”,
New出来的字符串,存放在栈中,与字符串常量的地址肯定不同。
s.intern()想要将new出来的字符串放入到常量池中,由于字符串常量已经存在,所以它们没有关系。
创建s3字符串对象“aa”,由于在字符串常量池中没有“aa”常量,则将字符串对象“aa”的副本放入到字符串常量池中,s4引用常量池中的副本,但是副本与原本并不是同一个对象,它们分别存在于字符串常量池和堆中,所以地址不同。
在这里插入图片描述
Jdk6,只能将字符串对象的副本放入到常量池中,而jdk6+,则可以将字符串对象的引用放入到常量池中。
所以,s3的引用存在堆中,s4先去常量池中寻找,找到了s3调用intern()后,存放在常量池中的引用,也就是引用了s3字符串对象,引用的地址相同,返回true。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值