JAVA实例
1. 类(class)与对象(object)
Class类注释对于Class的定义: Class 类的实例表示正在运行的 Java 应用程序中的类和接口。Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。 可以知道每个class也是特殊的对象,不过是java虚拟机创建。class的获取:
- 如 Class arrayListClass = ArrayList.class; Q:此处的class是什么(属性?关键字?)
- public final native Class<?> getClass(); 此方法来源于object
- 通过类加载器,显式加载类,获取class (显示加载,隐式加载,双亲委派,SPI,自定义classLoader)
类的生命周期
其中要注意的是 static修饰的成员变量,其生命周期与非static修饰的不同,于此产生的相互访问的限制。还需注意观察反编码后的this关键字。
一个类卸载垃圾回收的条件:
JSP的热加载,可以参考。
2. 实例生成
- 使用new关键字 (需要public修饰的构造方法,默认的无参构造会有被覆盖隐藏问题,使用框架时需要注意。也可以通过控制构造方法的访问修饰符,实现单例模式-懒汉|饿汉(双重检查锁)|静态内部类|枚举-。还有lombok插件(Q:编译时对代码修改?))
Q:访问修饰符可以通过暴力反射绕过,修饰符也代表着约定规则 - Class类的newInstance方法。
- Constructor类的newInstance方法
- clone(实现Cloneable接口)
- 序列化与反序列化(实现Serializable或Externalizable )(Json与对象的转换,fastJson)
Class类与反射:
反射相关类在 java.lang.reflect 包中,可以通过class获取定义在类中的相关参数,如 Constructor,Field,Method,WildcardType,annotation等信息,并提供相应的操作,如给field赋值,调用方法。
3. object
object类的方法:
主要为:克隆,垃圾回收,获取class,equals与hash和toString,线程唤醒等待
根据《深入理解java虚拟机》:
需要注意的是锁(无锁,偏向锁,轻量级锁,重量级锁。自旋锁,悲观锁,乐观锁,注意与mysql中的结合理解)
synchronized与对象锁,类锁
实例对象与堆: jvm规范: 栈、堆、方法区(1.8改为元数据区)
-
栈: 每个线程一个栈,方法的调用即栈帧的创建销毁。尾递归的栈优化
-
堆:几乎所有的对象在此分配(JIT编译器、逃逸分析技术,采用栈上分配和标量替换优化技术,使得对象不局限于堆)。heap为垃圾收集的主要区域,故称“GC堆”,从GC回收角度可分为,新生代(1/3)、老年代(2/3),新生代细分为Eden、FromSurvival、ToSurvival(8:1:1)。
关于对象实例化时内存的分配:
指针碰撞(内存规整适用,GC采用带compact的,如serial,parnew)。
空闲列表(GC:cms这种基于mark-sweep)。多线程,内存分配指针移动,多线程问题:1.TABL(对象创建在线程相关内存块上,同时共享,解决分配时的冲突) 2.CAS配上失败重试保证更新原子性(频繁冲突会降低性能)。 -
方法区
存放:被虚拟机加载的 类信息、常量、静态变量、及时编译器编译后的代码。
对象在jvm中的存活时间是不一样的,并且差异大。根据存活时间进行位置分配,并采用相应的回收策略,由此产生的存储区域或连续,或分散,对象在分配内存区域时采用不同的方式。