分享

jvm内存模型

liuyuze_hanbing 发表于 2017-9-27 11:43:50 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 5394
一、内存模型
运行时数据区包含
方法区:所有线程共享
堆:所有线程共享
java栈:线程独享自己的空间
pc寄存器(程序计数器)、线程独享自己的空间
本地方法栈:hotspot的本地方法栈和java栈在一起

java栈
    创建新线程时,jvm都会分配一个java栈,jvm只会正对java栈执行进栈出栈两种操作。
    java栈是由许多栈帧组成[stack frame],一个栈帧包含一个java方法调用的状态。当线程调用一个java方法时,虚拟机压入一个新的栈帧到java栈中,方法返回时,弹出该栈帧。
    一个新的线程被创建时,它都将得到属于自己的pc寄存器(程序计数器)和一个java栈
    线程执行方法时,pc寄存器的值总是指向下一条将被执行的指令,而该线程的java栈总是存储正在调用的方法中的状态--局部变量、入参、返回值、中间结果等,都是线程私有的。

    本地方法的调用:依赖具体实现存储在本地方法栈中或寄存器,也可能是特定实现相关的内存区。

方法区:jvm规范规定的一个概念,hotspot的实现为永久代1.8后放弃了
存储被装载类的信息
    全类名
    直接超类的全类名列表
    类的类型:类或接口
    访问修饰符:public、abstract、final等
    常量池:虚拟机为每个被装载的类维护一个常量池,是常量的有序集合。包括直接常量和对其他类型、字段、和方法的符号引用。编译时常量是指final的和编译时已知初始值的类变量
    字段信息:按照字段的声名顺序保存字段名、字段类型、修饰符
    方法信息:方法名、返回类型、参数个数和类型(按声名顺序)、修饰符,如果不是抽象方法或本地方法还保存方法的字节码、操作数栈和该方法的栈帧中的局部变量区的大小、异常表
    除了常量以外的所有静态变量:
    一个装载该类的ClassLoader引用
    一个到该类的引用:每一个被加载的类,虚拟机都会相应的为它创建一个java.lang.Class实例,虚拟机必须把这个实例和方法区中的类型数据关联起来

    对方法区数据的访问必须是线程安全的,因为方法区是所有线程共享的
    方法区大小不必是固定的,虚拟机可以根据应用程序的需要动态调整。可以是不连续的,可以在一个堆(甚至是虚拟机自己的堆)上自由分配,可以由用户指定初始大小最大最小等
    可被垃圾回收:回收一些不在引用的类
    JDK1.8永久代(Permanent Generation )的替代者:元空间(Metaspace),JVM参数PermSize 和 MaxPermSize会被忽略,当前在启动时会有警告信息
   

    java运行时创建的所有类实例和数组都放在同一个堆中。
    java对象的基本数据由自己和父类的实例变量组成

程序计数器
    每个线程都有自己的pc寄存器,他是在线程启动时创建的,pc寄存器的大小的一个字长,因此既能持有一个本地指针又能持有一个retureAddress。当线程执行某个java方法时,pc寄存器的内容总是下一条将被执行的指令地址。这个地址可以是一个本地变量也可以是在方法区字节码中相对于该方法起始指令的偏移量。如果正在执行本地方法,此时值是undefined

本地方法栈
未知
直接内存
    Nio:基于channel和buffer的io方式,native函数直接分配堆外内存,DirectByteBuffer对象作为这块内存的引用
元数据区(Metaspace)hotspot JDK1.8开始使用
    [JEP122][2]提议取消永生代,方法区作为概念上的区域仍然存在。原先永生代中类的元信息会被放入本地内存(元数据区,metaspace),将类的静态变量和内部字符串放入到java堆中。
    元数据区放在本地内存中   
    MaxMetaspaceSize设置元数据区大小
    如果类元数据的空间占用达到参数“MaxMetaspaceSize”设置的值,将会触发对死亡对象和类加载器的垃圾回收。

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条