首页 > 代码库 > JVM:Java内存区域

JVM:Java内存区域

  • Java虚拟机运行时数据区:方法区、虚拟机栈、本地方法栈、堆、程序计数器
    1. 由所有线程共享的数据区:方法区、堆
    2. 每条线程都需要有一个独立的程序计数器
    3. 虚拟机栈:线程私有,用于存储局部变量表、操作数栈、动态链接、方法出口等
    4. 方法区:存储类信息、常量、静态变量、即时编译后代码。jdk1.7已将字符串常量池移出
    5. 运行时常量池:String的intern()
    6. 直接内存(Direct Memory):不受JAVA堆大小限制,受本机总内存限制(-XX:MaxDirectMemorySize)
  • 对象的创建
    1. 遇到一个new指令时,首先将去检查这个指令的参数能否在常量池中定位到一个类的符号引用,并检查这个符号所引用的类是否已被加载、解析和初始化
    2. 虚拟机为新生对象分配内存:指针碰撞和空闲列表
    3. 内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值
    4. 虚拟机需要对对象进行必要的设置:对象头
    5. 执行new命令后执行<init>方法
  • 对象的内存布局
    1. 三块区域:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)
    2. 对象头分两部分信息:第一部分是哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳
    3. 第二部分是类型指针,即对象指向它的类元数据的指针
  • 对象的访问定位
    1. 通过句柄访问:对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改
    2. 直接指针访问:速度更快,节省了一次指针定位的时间开销
  • 内存泄露
    1. 通过查看泄露对象到GC Roots的引用链
    2. -XX:+HeapDumpOnOutOfMemoryError
  • 虚拟机栈和本地方法栈
    1. 使用-Xss减少栈内存容量
    2. 如果建立过多线程导致的内存溢出,在不能减少线程数或更换64位虚拟机的情况下,只能通过减少最大堆和减少栈容量来换更多的线程


JVM:Java内存区域