Java JVM内存区域详解

 更新时间:2021年11月02日 15:27:18   作者:聪明墨菲特  
下面小编就为大家带来一篇基于jvm java内存区域的介绍。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

原网页:JavaGuide

JVM在执行Java程序过程中会把它管理的内存划分成若干个不同的数据区域。JDK1.8和之前的版本略有不同,下面会介绍到。

JDK1.8之前

JDK1.8之后:

这其中线程私有的:

  • 虚拟机栈;
  • 程序计数器;
  • 本地方法栈;

线程共享的:

  • 堆;
  • 方法区;
  • 直接内存(非运行时数据区的一部分)

程序计数器

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器完成。

Java虚拟机栈

与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期和线程相同,描述的是Java方法执行的内存模型,每次方法调用的数据都是通过栈传递的。

Java内存可以粗糙的分为堆内存栈内存,其中栈就是现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分。(实际上,Java虚拟机栈是由一个个栈帧组成,每个栈帧中都拥有:局部变量表、操作数帧、动态链接、方法出口信息)。

局部变量表主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不同于对象本身,可能是一个指向对象的起始位置的引用指针,也可能是指向一个代表对象的句柄或其他于此对象相关的位置)。

方法/函数如何调用?

Java栈可以类比数据结构中栈,Java栈中保存的主要内容是栈帧,每一次函数调用都会有一个对应的栈帧被压入Java栈,每一个函数调用结束后,都会有一个栈帧被弹出。

Java方法有两种返回方式:

1、return语句。

2、抛出异常。

不管哪种返回方式都会导致栈帧被弹出。

Java虚拟机所管理内存中最大的一块,Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。

Java世界中“几乎”几乎所有的对象都在堆中分配,但是随着JTI编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到对上也渐渐变得不那么“绝对”了。从JDK1.7开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。

Java堆是垃圾收集器管理的主要区域,因此也被称作GC堆。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以Java堆还可以细分为:新生代和老年代;进一步细致一点还有:Eden空间、From Survivor、To Survivor空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。

在JDK7版本以及JDK7版本之前,堆内存通常被分为以下三部分:

1、新生代内存

2、老生代

3、永生代

JDK8版本之后,方法区被移除了,取而代之的是元空间,元空间使用的是直接内存。

 大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • mybatis plus or and 的合并写法实例

    mybatis plus or and 的合并写法实例

    这篇文章主要介绍了mybatis plus or and 的合并写法实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java数组优点和缺点_动力节点Java学院整理

    Java数组优点和缺点_动力节点Java学院整理

    本文给大家简单介绍下java数组的优点和缺点知识,需要的的朋友参考下吧
    2017-04-04
  • IDEA 开发多项目依赖的方法(图文)

    IDEA 开发多项目依赖的方法(图文)

    这篇文章主要介绍了IDEA 开发多项目依赖的方法(图文),本文讲一下关于使用IntelliJ IDEA基于Maven创建多模块项目的实际开发,非常具有实用价值,需要的朋友可以参考下
    2018-10-10
  • 关于yml文件字符串,List,Map的书写方式并使用@ConfigurationProperties注入配置类

    关于yml文件字符串,List,Map的书写方式并使用@ConfigurationProperties注入配置类

    这篇文章主要介绍了关于yml文件字符串,List,Map的书写方式并使用@ConfigurationProperties注入配置类,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • JDBC利用C3P0数据库连接池连接数据库

    JDBC利用C3P0数据库连接池连接数据库

    这篇文章主要为大家详细介绍了JDBC利用C3P0数据库连接池连接数据库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • 基于Spring Batch向Elasticsearch批量导入数据示例

    基于Spring Batch向Elasticsearch批量导入数据示例

    本文介绍了基于Spring Batch向Elasticsearch批量导入数据示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • springmvc组件中的HandlerMapping解析

    springmvc组件中的HandlerMapping解析

    这篇文章主要介绍了springmvc九大组件中的HandlerMapping解析,HandlerMapping表示的是一个URL与一个Handler(可以简单的理解为Controller中有@RequestMapping注解的方法)之间的映射关系,需要的朋友可以参考下
    2023-09-09
  • 详解Spring MVC3返回JSON数据中文乱码问题解决

    详解Spring MVC3返回JSON数据中文乱码问题解决

    本篇文章主要介绍了Spring MVC3返回JSON数据中文乱码问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • SpringBoot实现动态定时任务的示例代码

    SpringBoot实现动态定时任务的示例代码

    在SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务执行时间,实在不太灵活。现在我们就来实现可以动态修改cron表达式的定时任务,感兴趣的可以了解一下
    2022-10-10
  • Java守护线程和用户线程的区别

    Java守护线程和用户线程的区别

    这篇文章主要介绍了Java守护线程和用户线程的区别,用户线程和守护线程,默认情况下我们创建的线程或线程池都是用户线程,所以用户线程也被称之为普通线程,下文更多详细内容需要的小伙伴可以参考一下
    2022-05-05

最新评论