java内存结构

1、内存结构图

 

2、栈

操作数栈:每一个方法就是一个栈帧;每一个独立的栈帧中除了包含局部变量表以外,还包含一个后进先出(Last-In-First-Out)的操作数栈,也可以称之为表达式栈(Expression Stack)。操作数栈和局部变量表在访问方式上存在着较大差异,操作数栈并非采用访问索引的方式来进行数据访问的,而是通过标准的入栈和出栈操作来完成一次数据访问。每一个操作数栈都会拥有一个明确的栈深度用于存储数值,一个32bit的数值可以用一个单位的栈深度来存储,而2个单位的栈深度则可以保存一个64bit的数值,当然操作数栈所需的容量大小在编译期就可以被完全确定下来,并保存在方法的Code属性中。

动态链接:每一个栈帧内部除了包含局部变量表和操作数栈之外,还包含一个指向运行时常量池中该栈帧所属方法的引用,包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)。在运行时常量池,一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息外,还包含一项信息,那就是常量池表(Constant Pool Table),那么运行时常量池就是字节码文件中常量池表的运行时表示形式。在一个字节码文件中,描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用(Symbolic Reference)来表示的,那么动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用

方法返回值:一个方法在执行的过程中将会产生两种调用结果:一种是方法正常调用完成,而另外一种则是方法异常调用完成。如果是方法正常调用完成,那么这就意味着,被调用的当前方法在执行的过程中将不会有任何的异常被抛出,并且方法在执行的过程中一旦遇见字节码返回指令时,将会把方法的返回值返回给它的调用者,不过一个方法在正常调用完成之后究竟需要使用哪一个返回指令还需要根据方法返回值的实际数据类型而定。在字节码指令中,返回指令包含ireturn(当返回值是boolean、byte、char、short和int类型时使用)、lreturn、freturn、dreturn以及areturn,另外还有一个return指令供声明为void的方法、实例初始化方法、类和接口的初始化方法使用。

运行常量池:

默认不是new的时候会直接把我们的字符串对象放入我们的常量池之中,所有s1==s2返回是为true
使用new的会后会在堆内存中创建对象所以的到的S3==S1返回的值为false
在调用我们intern方法之后会把这个放入常量池中。这时候因为常量池类似于hashSet则他们引入地址值就会一样导致s3.intern() == s1返回true

 

 

3、堆:大对像,new的对像都是放在堆区间,new出来的对像也可能栈上分配;

创建对像分配空间的两种方法;使了那种方法与垃圾回收有关;

指针碰撞:

空闲列表:

栈上分配:当一个方法里创建的对像没有被外部方法或者属性引有时;则该方法中new的对像就放在栈里面;

//方法区的对像未被外部方法或者属性引用;该对像存在栈中,叫栈上分配
public
void a(){ Object a=new Object(); a.toString(); }

 

内存逃逸分析:对像跳出来栈桢,放堆里面了

//如下对像被外部属性引用了;就无法分配在栈里面了;只能分配到堆里
public
class Test { private Object o; public void a(){ o=new Object(); } }

 

  

创建对像:

  对像有以下三部分组成:

      对像头:hash值,类型指针 ; 

public static void main(String[] args) {
     Object o1=new Object();
     Object o2=new Object();
     //结果返回为true是因为这两个对像getClass指的是同一个对像类型;类型指针是一样的
     System.out.println(o1.getClass()==o2.getClass());
}

      实例数据:对像的属性

      填充数据:java虚拟机要求对像是8位的倍数;但对像中有数据存在4位的数据时,会自动填充

posted on 2019-12-19 11:28  JAVA-ROAD  阅读(252)  评论(0编辑  收藏  举报

导航