Java虚拟机从入坑到入土

Posted Java从入坑到入土

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java虚拟机从入坑到入土相关的知识,希望对你有一定的参考价值。


今天来了解一下Java的内存区域分为哪些部分及各个部分的功能特点,本文的所有知识均由笔者从《深入理解Java虚拟机》归纳及总结,若有任何理解不恰当的地方,欢迎大家向我提出!非常乐意与你们交流!


首先我们来看看Java的运行时数据区域

也许第一次看到这幅图的时候,我们都会有一种感觉就是很乱,不知道是什么东西,我们可以将运行时数据区里面的五大区域分成两大部分

一、线程共享

所有线程都会共享这些区域,线程的相关操作都会对其它线程可见并有可能带来影响。

1. 堆

  • 堆的作用是存储对象实例,也就是我们最常见的使用对象时,必须要先new一个对象

  • 它是内存最大的一块区域

  • 它是垃圾回收器的主要区域:Java和C++的区别就好比吃完饭以后,如果我们要自己把垃圾扔到垃圾桶里面,那么就是C++;而如果我们吃完饭不用主动扔垃圾,垃圾会被其他打扫卫生的清洁人员回收,那么这就是Java的特性,不用自己去回收垃圾。而交给垃圾回收器去回收。

  • (了解)Java堆可细分为新生代和老年代、Eden空间、Survivor空间······这些都是为了方便垃圾回收器识别各种不同的对象的特性,提高回收垃圾的效率,但是各个空间都是存储对象实例,没有任何存储内容上的区别

  • 当堆中的内存被使用完并且无法再扩展时,就会抛出OutOfMemoryError异常。

2. 方法区(近乎于"永久代")

  • 方法区的作用是存储已经被JVM加载的信息:类信息、常量、静态变量、即时编译器编译后的代码、常量池

  • 方法区可选择不实现垃圾回收,因为大部分数据进入方法区就是"永久"存在的了;方法区进行垃圾回收的目标主要是常量池的回收及类型的卸载

  • 当方法区无法满足内存分配需求时会抛出OutOfMemoryError异常

2.1 运行时常量池

  • 它是方法区的其中一部分,具备动态性:在运行期间能够将新的常量放入池中,典型的例子是:String.intern()

  • 当它无法向方法区申请到内存时会抛出OutOfMemoryError异常

二、线程私有

每个线程创建时都会有自己独立的区域、线程之间不互相共享这些区域!

1. 程序计数器

  • 调用native方法时程序计数器不工作,指向空

    • native方法指的是在Java中可调用的方法,但是方法体不是由Java代码编写的,有可能是由C或C++编写的

    • 由于不是由Java语言编写的方法,自然也无法生成字节码,并且C/C++方法执行时的内存分配是由其语言本身决定的,不能由JVM决定。

  • 程序计数器是唯一一个不会抛出异常的区域,因为其占用的内存非常的小,可忽略不计

2. Java虚拟机栈

  • 执行Java方法每个方法在执行时都会创建栈帧,方法执行结束后,栈帧会弹出虚拟机栈,相信大家会对这句话有点印象,在初学Java时会听说过方法压栈执行和结束弹栈这两个概念。

    • 栈帧是方法运行的基本数据结构,它主要含有局部变量表、操作数栈、动态链接、方法出口······

    • 局部变量表在编译期完成内存分配,也就是说在栈帧中局部变量表需要多少内存空间是完全确定的,不会在程序运行时改变。

  • 当线程请求的栈帧深度大于Java虚拟机栈的深度时,无法继续放入栈帧,此时会抛出StackOverFlow异常

    • 常见情况:死递归(晕乎乎~)

  • 当虚拟机栈请求的内存空间大于主机内存时,会抛出OutOfMemoryError异常,虚拟机栈内存不可能大于主机内存!

returnAddress类型个人理解:

我认为这也就是为什么在执行返回值为void类型的方法时也可以手动添加return ;去提前终止方法的原因。

3. 本地方法栈

  • 执行native方法,什么是native方法在上面有介绍

  • 它和Java虚拟机栈的作用几乎是一样的

  • 为什么将本地方法栈和Java虚拟机栈不合二为一呢?

    • 在著名的Sun HotSpot虚拟机中就是将它们合二为一了,具体细节没有深究,有兴趣的读者可以去了解了解。

  • 它同样也会抛出与Java虚拟机栈相同的两个异常

三、结尾


感谢你们阅读我编写的推文!今天就介绍这么多啦,希望能让你们对于JVM的运行时数据区域有一个初步的了解,起码你会了解到JVM会分为哪几个区域,它们各自的功能是什么,尽管这都是一些基础性的概念知识,但是我认为基础的知识也是非常重要的,如果我有任何写得不正确和不准确的地方,欢迎大家向我提出来,我们可以一起学习和交流!

2019年9月20日

小菠萝

以上是关于Java虚拟机从入坑到入土的主要内容,如果未能解决你的问题,请参考以下文章

Flutter开发之dart语言从入门到精通(从入坑到入土)

Flutter开发之dart语言从入门到精通(从入坑到入土)

全方位解析Java学习路线图,从入坑到年薪百万

TypeScript进阶开发——ThreeJs基础实例,从入坑到入门

使用vue-select,从入坑到跳坑

从入坑到不放弃-----centos7系统软件安装方法及网站环境搭建