JVM内存区域

本文详细介绍了JVM的内存区域,包括程序计数器、栈、本地方法栈、堆、方法区(元空间)及运行时常量池。讲解了各区域的作用、分配策略以及GC行为。特别强调了新生代、老年代的GC算法和对象创建的过程。还讨论了栈上分配优化、内存溢出的情况以及堆参数设置的影响。
摘要由CSDN通过智能技术生成

JVM内存区域

程序计数器

当前线程执行字节码文件的行号指示器,各线程独立互不干涉。线程私有。(不会内存溢出)

每个方法在执行时都会创建一个栈帧。用来存储数据和部分过程结果的数据结构。存储局部变量表,操作数栈,动态链接,方法出口等信息。方法结束销毁

本地方法栈

native方法的信息。无需创建栈帧,直接动态链接到这个区域的对应方法,直接调用native方法。

创建的对象和数组保存在这里。垃圾回收的重要内存区域。从gc的角度还可以分为(Eden 区、From Survivor 区和 To Survivor 区)和老年代)//栈上分配的对象存在栈中

方法区(永久代、元空间)

被jvm加载的类信息,常亮,静态变量,即时编译后的代码等数据。
不会在运行期间堆永久代进行gc,随意可能会因为class太多而oom
1.8以后没有了永久带。改成了元空间。最大的区别在于,元空间不在虚拟机中,使用本地内存。

运行时常量池

是方法区的一部分。编译期的各种字面量和符号引用。(1.8之后属于堆的一部分)

从gc的角度,把堆分成新生代(minor gc),老年代(major gc),永久代(full gc)

新生代

eden区(对象诞生于此),server from区。server to区。eden不够用会触发minorGC(复制算法:复制-清除-置换)
大对象直接进入老年代,复制的时候空间不够直接进入老年代

老年代

满了会进行majorGC(标记清除算法)1.耗时长2.产生内存碎片

栈上分配

栈上分配:开启栈上分配可以提高性能,同时要开启逃逸分析和标量替换。
对象不会分配到堆中,而是直接分散存储在栈中。

虚拟机中的对象

new一个对象时基本上是这5步:
1.执行对应的类加载过程
2.在堆中划分一块区域给对象(可能会采用指针碰撞,或者空闲列表两种方式,这取决于堆是否规整。而是否规整取决于gc算法)
这里还要注意线程安全的问题:可以预分配一块区域给不同的线程(本地线程分配缓冲)还有一种方式是同步处理分配内存空间的动作,使用cas的方式。
3.内存分配好后,虚拟机初始化内存空间,赋初值
4.包装对象头。哪个类的实例,如何能找到元数据,对象的哈希,gc的年代年龄等,包装到对象头。
5.创建完成,程序员拿到了对象,可以开始初始化对象了。

堆参数设置和内存溢出

堆溢出:分配了巨型对象,或者循环大量分配对象。动态生成大量class。或动态生成大量jsp等。
栈溢出:递归,超过了最大深度;申请扩容时没有空间了。
本地直接内存溢出:本地内存不够用了。(元数据太多了)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值