Java内存区域

运行时数据区域

程序计数器

线程中一块较小的内存空间。存放相当于取指令的指针,指向下一条需要执行的字节码指令。
程序计数器线程存在于线程创建到销毁之间,由于每个线程的指令位置是不可混乱的,故程序计数器是线程私有的。

主要作用为
1.实现代码流程控制:顺序执行,选择,循环等。
2.多线程时记录当前线程的位置,便于恢复线程。

Java虚拟机栈

随着线程创建而存在线程私有的内存,可以类比于数据结构中的栈,用于存放栈帧。
会出现的两种错误:
StackOverFlowError:
栈的内存大小不允许动态扩展时,当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 错误。
OutOfMemoryError:
栈的内存大小可以动态扩展时, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

主要作用:
每次方法调用都会有一个对应的栈帧被压入 Java 栈,每一个函数调用结束后,都会有一个栈帧被弹出。

本地方法栈

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。方法执行完毕后相应的栈帧也会出栈并释放内存空间
虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。

Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建。是垃圾收集器管理的主要区域,因此也被称作GC 堆。
从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代;再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。
在这里插入图片描述
JDK 8 版本之后方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是直接内存。
在这里插入图片描述
上图所示的 Eden 区、两个 Survivor 区都属于新生代(为了区分,这两个 Survivor 区域按照顺序被命名为 from 和 to),中间一层属于老年代。

主要作用:
存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。

常用参数:
-XX:PermSize=N //方法区 (永久代) 初始大小
-XX:MaxPermSize=N //方法区 (永久代) 最大大小,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen
-XX:MetaspaceSize=N //设置 Metaspace 的初始(和最小大小)
-XX:MaxMetaspaceSize=N //设置 Metaspace 的最大大小

将永久代 (PermGen) 替换为元空间 (MetaSpace)的原因:
整个永久代有一个 JVM 本身设置的固定大小上限,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是比原来出现的几率会更小。

运行时常量池

运行时常量池是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有常量池表(用于存放编译期生成的各种字面量和符号引用),会受到方法区内存的限制。

直接内存

JDK1.4 中新加入的 NIO(New Input/Output) 类,引入了一种基于通道(Channel)与缓存区(Buffer)的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为直接内存的引用进行操作。这样就能在一些场景中显著提高性能,因为避免了在 Java 堆和 Native 堆之间来回复制数据。

HotSpot虚拟机对象

对象创建过程

类加载检查()
内存分配(从java堆中划分出来)
初始化零值(保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用)
设置对象头
执行init方法(把对象按照程序的意愿来初始化)

对象的内存布局

对象头;
1.存储对象自身的运行数据(哈希码、GC 分代年龄、锁状态标志等)
2.类型指针:虚拟机通过这个指针来确定这个对象是那个类的实例

实例数据:对象真正存储的有效信息,也是在程序中所定义的各种类型的字段内容。

对齐填充:起占位作用。对象的大小必须是 8 字节的整数倍,不满足时通过对齐填充来补全。

对象的访问定位

句柄: Java 堆中将会划分出一块内存来作为句柄池,reference为句柄地址,在句柄池中找到对象实例数据和对象类型数据的指针。

直接指针:reference 中存储的直接就是对象的地址

字符串常量池常见问题

待更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值