java有5个运行时数据区域,分别是java堆、java虚拟机栈、本地方法栈、方法区、程序计数器。
其中,在HotSpot (一款java虚拟机)中,虚拟机栈和本地方法栈是合在一起的。
程序计数器,线程私有,记录字节码指令位置,相当于字节码的行号指示器,能给程序下一步的运行进行指向。如果执行的是本地方法,它的值会变成0,因为本地方法不是用java写的,有别的机制去管。他是唯一没有处理OOM情况的内存区域。
java堆,线程共享,存放对象实例和数组,占内存的大头。它的大小可固定可扩展,虚拟机指令
-Xms 指定堆内存最小值;
-Xmx 指定堆内存最大值;
-Xmn 指定年轻代大小。
是垃圾回收的主要区域。
java虚拟机栈,线程私有,每调用一个方法就会创建一个栈帧,存放局部变量表(基本数据类型,对象引用等)、操作数栈方法出口等信息,栈帧的出栈入栈代表着调用方法和结束调用。
-Xss 栈大小
本地方法栈,与虚拟机栈差不多,只不过服务的是本地方法。
方法区,线程共享,存放已被虚拟机加载的类元数据信息、常量、静态变量、即时编译后的代码等。回收目标主要是常量池和类的卸载
虚拟机指令,-XX:MaxPermSize 永久代大小
java8 移除了永久代,指令改为 -XX:MaxMetaspaceSize
- 运行时常量池,方法区的一部分,存放编译后的字面量和符号引用。相关方法,string.intern()。
对象的内存布局,分为对象头、实例数据和对齐填充。
对象头又分为对象运行时数据和类元数据指针两部分。如果对象是数组,还需要分出一部分内存存放数组长度。
- 运行时数据(Mark Word)有哈希码、GC分代年龄、锁标志等。
实例数据记录了所有父类和子类自己的字段内容。
对齐填充实际是占位符,因为对象大小只能是8字节的整数倍,所以字节数不符合,就靠它来补齐。
网友评论