当Integer和int比较时,java会自动对int装箱(Integer.valueOf),由于大多数int比较都在128以下,因此java将-128到127的数放入了缓存,返回的是缓存中的同一个对象而不是新的对象
类加载主要有三个过程,装载,连接,初始化;装载是指查找和导入class文件到内存中,连接则是根据class二进制数据生成对象,这里会进行类的校验保证数据符合jvm规范,静态变量内存分配和符号引用的解析;初始化则是类的初始化操作,这里会进行静态变量和静态代码块的初始化,执行类的构造器。
jvm中有三类加载器,启动类加载器,扩展类加载器和应用类加载器,双亲委派机制是说当应用类加载器需要加载一个类时不会直接加载而是到父加载器中查找,找不到就找祖加载器,只有都找不到时才会自己加载。
每个类加载器都有自己的加载范围以保证内存隔离,对于同一个类的评判标准是:类名一致,类加载器一致,类加载器实例一致。
不会生效,因为父类加载器已经加载了string.class,当其他类加载时会直接加载系统的string.class
扩展类加载器在加载类时使用了concurrentHashMap和synchronized,concurrentHashMap保证了只有一个线程能往里面放对象,而synchronized则保证了加载时只有一个类能被加载
自定义类加载器通常是继承扩展类加载器,实现自身findclass方法,如果要破坏双亲委派则要重写loadclass方法
有两种方式,一种是使用OutputStream类的wirteobject方法,二种是实现Serializable接口
创建file类对象,调用exist方法判断是否存在,并使用isfile方法判断是否是文件还是目录,目录的话可以使用listfile列出目录下所有文件和子目录
三种系统的io处理模式,他们都是同步io,使用的多路复用器,当有流需要处理时必须自己处理。
java代码编译成.class存在操作系统兼容问题,而jdk是根据操作系统安装的,所以jdk中的jvm加载class文件可以屏蔽掉操作系统的兼容性问题
jmm是java内存模型,和cpu硬件结构相似,每个线程有自己的工作内存空间,并与主内存交互,当有新的变量时首先写入主内存然后拷贝到工作内存,好处是可以提高处理速度,并且线程之间内存隔离。
堆存放动态产生的数据,如new的对象,而栈存放局部变量,包括基础数据类型的值和对象的引用
堆分为新生代,老年代,永久代(常量池,元数据),java 内存分配和回收的策略是分代分配分代回收,java young gc采用的是停止-复制清理法。新生代分为eden区和两个存活区,当一个对象被创建时首先分配到eden区中,当eden区满时触发young gc将消亡的对象清理掉并把存活的对象复制到存活区0;之后,young gc在清理eden的同时清理存活区0,把存活的对象复制到存活区1,此时存活区0清空;如此反复,两个存活区总有一个是空的,每切换一次存活对象的年龄加1,当多次切换后(默认年龄是8)仍存活的对象将复制到老年代;当老年代满时触发full gc。如果存入eden区的对象非常大,超过eden区的大小则会直接放入老年代。
jvm判断是否是垃圾对象用的是可达性分析法,判断这个对象是否有引用; 使用system.gc主动触发full gc;