浅谈java的内存结构

java的内存结构

今天我们来谈谈java的内存结构,学习java的时候我们都知道java的内存结构大致分为堆和栈两个部分,但是强大的java不可能就这么简单,接下来我们来详细谈谈java的内存结构,先看看图,有点潦草但是还能看哈哈。
在这里插入图片描述
1.类加载器:用来负责加载.class文件到内存中,关于类加载会在下一章详细讲解。

2.方法区(永久代):在jdk1.8以后被称作元空间,它是线程共享的,不属于堆的一部分,方法区中保存着类被加载的各种信息,比如类的全限定名,父类的全限定名,修饰符等,方法区内部有一个常量池,他保存了类运行时所需要的常量,字面量,静态变量等信息。
jvm可以根据应用需要动态调整方法区,方法区可以不是连续的,也可以手动配置方法区的内存空间,当无法满足内存需要抛出OutOfMemoryError异常。

3虚拟机栈:首先它是线程私有的,线程之间相互不可见,是个线性结构,保持着先进后出的原则,主要存储局部变量,基本数据类型变量和对象的引用。
当一个方法执行时这个方法就会记载到栈中,并和堆中的对象进行关联,我们管他叫做压栈。
当一个方法结束时,这个方法将会从栈顶弹出,我们管他叫做弹栈。
当栈内存不满足需要时抛出StackOverflowError 异常。

4.本地方法栈:线程私有,它是为java的底层的本地方法服务,也就是调用底层的c语言,本地方法栈也会抛出StackOverflowError 异常。

5.程序计数器:它是一个较小的内存空间,记录当前线程执行的字节码的位置,每个线程都有一个独立的计数器,所以它必须是线程私有的,由于线程在执行当前字节码时是轮流切换的,这就需要程序计数器来进行记录当前线程执行到了那里,当下次这个线程抢到cpu时间片时会从什么地方开始继续执行。
6.堆:所有创建出来的对象都会存放在堆区,堆区也是gc(垃圾回收器)常驻的区域,堆是所有线程共享的区域,堆区分为:主要分为年轻代和老年代,年轻代又分为:Eden区,from区和to区,当不满足内存需要抛出OutOfMemoryError异常。我们先来看图。
在这里插入图片描述
Eden区:主要存放新出生的对象,也就是说刚刚创建的对象他都会在这里,这个区域也是gc非常活跃的地方。
from区和to区:这两个区域大小一样,当Eden区满时将会把存活的对象放入这两个区域的其中一个,具体怎么样存放和gc的运行机制有关,gc使用复制算法,将存活的对象整体转移到另一个区域,然后将这个区域清空。
老年代:这个区域存放存活的很久的对象,这个区域相对于年轻代gc出现的次数比较少。

JVM的担保机制:当年轻代的空间不够存放一个新的对象的时候,JVM会把对象整体转移到老年代里面去。
当存放非常大的对象的时候,JVM发现在Eden区创建好的对象过大无法转移到from区或to区,并且刚刚新创建的对象它们加起来又超过了年轻代的内存空间,JVM会把原有的对象直接移入老年代中,腾空出来的年轻代用来给新创建的对象分配空间。

一位小白,如有理解错误请大神纠正,感谢阅读。

猜你喜欢

转载自blog.csdn.net/weixin_45118251/article/details/90552363
今日推荐