JVM学习笔记一:Java内存区域
2015-07-18 10:40
645 查看
在虚拟机自动内存管理机制的帮助下,java程序员不需要去关心每一个对象的内存回收,不容易出现内存泄露和内存溢出问题,由虚拟机管理内存,看起来不需要程序员知道jvm是如何分配和回收内存的。但是不明白jvm底层的运行机理,对于java程序的优化、以及jvm的一些错误改正就无从谈起。
1. 运行时数据区域
JVM所管理下的内存将会包括一下几个运行时数据区域:程序计数器
虚拟机栈
本地方法栈
方法区
堆
程序计数器
程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。当线程执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址;如果是Native方法,则为空(undefined)程序计数器为“线程私有”。虚拟机栈
JVM栈也是线程私有的,他的生命周期与线程相同。JVM栈描述的是Java方法执行的内存模型:每个方法执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出入口等。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。此区域有StackOverflowError和OutOfMemoryError异常
局部变量表存放编译期可知的各种基本类型(int、double……)、对象引用(reference)和returnAddress类型(指向一条字节码指令的地址)。64位,long和double会占用2个局部变量空间(SLot),其余都为一个。局部变量表所需内存空间在编译器完成分配。
本地方法栈
与虚拟机栈作用类似,但本地方发展为Native方法服务。此区域有StackOverflowError和OutOfMemoryError异常Java堆
全线程共享的一块区域,用于存放对象实例以及数组。是垃圾回收器主要管理区域。从内存分配的角度看,java堆中可能划分出多个线程私有的分配缓冲区(TLAB)。会有OutOfMemoryError异常
方法区
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,线程共享。该区域的内存回收主要是针对常量池的回收和对类型的卸载。2.对象
对象的创建
检查这个指令的参数是否能在常量池中定位到一个类的符号引用检查这个符号引用代表的类是否已被加载、解析和初始化
类加载检查通过后,为新生对象分配内存
对象的内存分配
1.指针碰撞
假设Java堆中内存是绝对规整的,所有用的内存都放在一边,空闲放在另一边。中间放着一个指针作为分界点的指示器,分配内存仅仅是将指针向空闲一侧移动。(Serial、ParNew)
2.空闲列表
Java内存不是规整的,已使用和未使用交错,虚拟机必须维护一个列表,记录内存使用情况,再分配时在列表中找到一块足够大的内存划分个对象。
对象的内存布局
对象在内存中的布局分为3块区域:对象头(Header)、实例数据(Instance Data)和对象填充(Padding)。
对象头:包括两部分信息,第一部分用于存储对象自身的运行时数据(如哈希码、GC分代年龄、锁状态标志、线程持有锁……),这部分数据的长度在32位和64位虚拟机中分别为32bit和64bit,官方成为“Mark Word”。另一部分是类型指针,即对象指向它的类元数据的指针。虚拟机通过这个指针确定这个对象是哪个类的实例。(如果是数组,则对象头还记录数组长度的数据)
实例数据是对象真正存储的有效信息.
对齐填充仅仅占位符的作用
对象访问定位
1.句柄2.直接指针
句柄:
java堆中划分出一块内存作为句柄池,reference中存储的就是对象的句柄地址。而句柄中包含了对象实例数据与类型数据各自的具体地址信息。
直接指针:
reference中存储的直接就是对象地址
相关文章推荐
- Java 6 JVM参数选项大全(中文版)
- Java虚拟机JVM性能优化(二):编译器
- Java程序员必须知道的5个JVM命令行标志
- Java虚拟机JVM性能优化(三):垃圾收集详解
- JAVA中JVM的重排序详细介绍
- Java虚拟机JVM性能优化(一):JVM知识总结
- Android Studio 报错failed to create jvm error code -4的解决方法
- 解析Linux系统中JVM内存2GB上限的详解
- xms/xmx/xss在kette中的调优设置
- JVM工作原理和特点
- 深入Java虚拟机
- JVM内存模型及垃圾收集策略解析
- JVM内存配置详解
- 关于String与StringBuilder的提问与总结
- 亮剑JVM的9款编程语言杀手开发利器重磅推荐
- JVM的监控与优化
- Tomcat/JVM常见问题排除及性能优化
- JVM 之 Class文件结构
- JVM 之 运行时数据区(更新)