我是一个普通的java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的,我在这里也认识了很多人。在年老代里,我生活了20年(每次GC加一岁),然后被回收。
三色标记算法:
黑色:自己标记完成,孩子也标记完成,下一次GC不会进行扫描
灰色:自己标记完成,孩子还没来得及标记,下一次GC扫描孩子
白色:没有遍历到的节点
JVM基础
class文件
常量池
//自定义类加载器
public class SelfClassLoader extends java.lang.ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
BufferedInputStream bis = null;
ByteArrayOutputStream baos = null;
try {
bis = new BufferedInputStream(new FileInputStream(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 super.findClass(name);
}
}
//使用自定义类加载器
public class ClassLoader {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
SelfClassLoader classLoader = new SelfClassLoader();
Class<?> aClass = classLoader.loadClass("D:/Son");
Father father = (Father) aClass.newInstance();
father.sleep();
System.out.println(aClass.getClassLoader());
System.out.println(father.getClass().getClassLoader());
System.out.println(classLoader.getClass().getClassLoader());
System.out.println(classLoader.getParent());
}
}
懒加载
class文件结构简单介绍:
class文件结构 对应一个类或者接口定义的信息。它的格式是被约定好的。
两个概念:
字面量类似于字符串和常量的值。符号引用包括三类常量,分别是类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。
常量池项类型:
常量有14种类型。 有些是字面量,有些有结构的常量类型 也叫表类型,表类型就是组合常量池中的其他字面量组合而成的。不同类型的项都有标记tag来标识,通过tag从而能够解析并得到这个的项的内部结构 而取到正确的值。
句柄和引用,句柄就类似于引用,表示的都是内存地址,当有多层应用时候会把其中的一层引用叫做句柄。
方法表中的属性:
code属性有几个比较重要,最大操作数栈。局部变量表的总存储空间,字节码指令长度,code属性用于描述代码,而其他所有
都是来描述元数据。所以也是字节码执行引擎内容的基础。
本地变量表属性,是用来描述局部变量表的变量与代码中定义的变量之间的关系。
每个方法至少有一个this的隐式的参数来指向调用该方法所属的对象。