java内存分配与垃圾回收

来源:互联网 发布:日本音乐知乎 编辑:程序博客网 时间:2024/06/04 18:57

一、线程共享内存区

         包括堆区。运行时常量池和方法区


二、java堆区

        实际的空间中不连续,GC的重点回收领域。java 对象的生命周期有长有短,故应采用不同的垃圾回收策略。故java堆区细分的话。可以划分为新生代(YoungGen)和老年代(OldGen)。新生代又划分为Eden空间。From Survivor空间和To Survivor空间。

        jdk配置文件中可修改相应的参数: “-Xmx”表示堆的起始内存。“-Xms”表示堆区的最大内存。


三、方法区

        存储每一个java类的结构信息,比如:运行时常量池、字段和方法数据、构造方法和普通方法的字节码内容以及类、实例、接口初始化时需要用到的特殊方法等数据。方法区逻辑上独立,实际属于堆区的一部分。但是它不像堆区那样频繁被调用。还可以显示指定是否需要在程序运行时回收,所以它被称为永久代。若无显式要求,GC的回收目标仅针对方法区中的常量池和类型卸载。


四、运行时常量池

       将类或者接口载入JVM后,就会创建阈值对应的运行时常量池。


五、线程私有内存区

      包括java栈、本地方法栈、PC寄存器(计数器)


六、PC寄存器

      若当前线程正在运行一个java方法,那么PC寄存器就会存储正在执行的字节码指令地址。反之若是native方法。则存储的值为空(undefined)。


七、java栈

     也成为java虚拟机栈,java栈用于存储栈帧,栈帧中存储的是局部变量表。操作数栈以及方法出口等信息。

   

八、本地方法栈

     用于支持本地方法。


九、内存分配原理

     当语法层面使用new关键字创建一个java对象时,JVM首先检查这个new 指令的参数能否在常量池中定位到一个类的符号引用,然后检查这个符号引用相对应的类是否已经成功经历过加载、解析和初始化等步骤。当类完成加载步骤后,就可以完全确定创建对象实例时所需要的内存大小。接下来JVM会对其进行内存分配,以存储所生成的对象实例。


TLAB (Thread  Local  Allocation  本地线程分配缓冲区)


十、逃逸分析与栈上分配

逃逸分析具体目标是分析出对象的作用域,一个对象被定义在方法体内部后,它的受访权限仅限于方法体内,一旦其引用被外部成员引用后,该对象就发生逃逸,反之,该对象并没有被任何外部成员引用时,JVM为其在栈帧中分配内存空间。