JVM

 

对象都是存在在堆上的吗?

不一定,Java中的对象不一定是在堆上分配的,因为JVM通过逃逸分析,能够分析出一个新对象的使用范围,并以此确定是否要将这个对象分配到堆上。

 

如果一个对象是在方法内部创建的,但是这个对象的引用没有传递到方法外,那么这个对象不会存在在堆上。

 

逃逸分析就是:一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针。

 

在JVM的即时编译语境下,逃逸分析将判断新建的对象是否逃逸。即时编译判断对象是否逃逸的依据:一种是对象是否被存入堆中(静态字段或者堆中对象的实例字段),另一种就是对象是否被传入未知代码。

 

典型的就是:在方法内部创建对象并发 对象的引用赋值给 方法外的变量,或者使用return Object 返回对象。

 

 

可能出现的异常

1 StackOverFlowError,Java虚拟机允许栈空间大小固定不变,比如无限递归,就会抛出异常。-Xss 规定了栈的最大空间,超出这个值就会报错

2 OutOfMemoryError,虚拟机栈可以动态扩展,如果扩展到无法申请足够的内存空间,内存不足,会出现OOM.

 

虚拟机中提供的几条方法调用指令:

  1. invokestatic 调用静态方法,解析阶段确定唯一方法版本

  2. invokespecial 调用<init>方法,私有及父类方法,解析阶段确定唯一方法版本

  3. invokevirtual 调用所有虚方法,public等虚方法

  4. invokeinterface 调用接口方法

  5. invokedynamic 动态解析需要调用的方法,然后执行。

前四条指令固化在虚拟机内部,不可人为干预,最后一条指令由用户确定具体调用方法的版本。

其中invokestatic,invokespecial指令调用的方法是非虚方法,其余的(final修饰的方法除外)都称为虚方法。

 

方法的重写与重载:

明确一个概念,方法的签名,方法的签名有 方法的名字 和 方法参数列表组成

 

重载:方法的签名不同

重写:方法的签名相同

 

重写是 Java 运行时的多态;重载 是Java 编译时的多态。

 

重写 使得 父类引用能 指向 子类的引用,执行父类方法。 方法的执行过程,父类和子类的继承关系,组成了一条链表,从子类 到达 父类, 从子类开始寻找,如果某个子类重写了 父类的方法,那么执行子类的重写的方法,否则继续向上寻找,直到执行父类的方法。

 

 

 

posted @ 2020-10-01 21:32  lfcom  阅读(90)  评论(0编辑  收藏  举报