Rumah Java javaTutorial JVM之内存管理

JVM之内存管理

Nov 21, 2016 pm 02:00 PM

  都说搞C的牛叉,那是因为C解决问题,全靠程序员自己,他们对自己的程序在内存中是什么样了如指掌。而Java呢不需要有太多操作系统的知识,不用时刻注意内存的问题,但这不代表我们就不用去了解它背后的原理,(其实我是被公司的C嘲讽了一下OoO)。Java之所以容易上手,那是因为最困难的问题,已经被前人解决了,而这一切都归功于Java Virtual Machine-Java虚拟机,JVM其实就是一个抽象的计算机,它有自己的指令集,有自己的机器语言,有自己的内存管理。本系列会一一解开它的真面目。

  本文基于Java HotSpot™ 虚拟机,JDK 1.8,将讨论:

JVM 内部结构

JVM 内存管理

JVM 内存模型

t0128f824aa7ed65fdd.png

图 1 JVM 内部结构

1. JVM 内部结构

  一个程序执行的过程是这样的,以C语言为例,源代码首先被编译成可执行文件,以二进制的形式存放到磁盘上,当执行时,首先从磁盘加载到内存中,然后处理器就开始执行目标程序中机器指令。反观Java,首先编译成字节码文件,与平台无关,JVM通过ClassLoader加载到内存中,然后执行其中的机器指令,JVM帮我们跟操作系统打交道。有了字节码和JVM,Java实现了平台无关性。JVM也可以认为是一个进程,在启动时申请一块内存,然后按照功能的不同,把内存分为以下不同区域:

(1) Heap

  堆,一个非常重要的区域,被所有线程共享,基本所有的对象实例都在这里分配,大部分的垃圾回收也发生在这里。这部分内存,由JVM使用Garbage Collector(自动内存管理工具)来管理,职责就是为对象分配内存,释放空闲内存。Java 堆的大小可以使用参数来控制是固定的,还是动态扩展的。

(2) JVM Stacks

  栈,与线程息息相关,线程私有,随线程生而生,死而死,是线程执行工作的内存。HotSpot中Java栈和本地方法栈合二为一,都在本地内存空间中分配,这部分内存就不需要JVM刻意的去管理了。JVM栈主要用来存储栈帧,当调用一个方法时创建一个栈帧,方法结束销毁,从栈的角度来看,就是入栈和出栈两个操作。

  栈帧是一个数据结构,用来存储局部变量,操作数栈,和当前类运行时常量池的引用。局部变量数组:用来保存方法内定义的基本类型变量,下标从 0 开始,JVM使用局部变量表传递方法参数,当调用一个实例方法,第 0 位置存储的是当前对象的 this 引用;操作数栈:用来执行运算和准备调用方法的参数以及方法的返回结果;动态链接:引用对象的运行时常量池。

(3) PC Register

  程序计数器,线程私有,主要作用就是存储指令地址,取指,解码和执行。每个线程都关联着唯一的栈和PC寄存器。

(4) Metaspace

  元空间,在JDK8之前的HotSpot VM称之为方法区或者永久代,被各线程共享,它存储了一个类的结构信息,如常量池、字段、方法等。存放在本地内存中,与堆不相关。

(5) Native Method Stacks

  JVM栈是为Java方法准备的,那么本地方法栈则是为虚拟机调用本地方法服务的。

2. JVM 内存管理

  Java不允许直接操作内存,内存的申请和释放统一交给虚拟机处理。

2.1 Garbage Collection 自动内存管理

  自动内存管理(以下简称GC)的职责:

分配内存

确保引用对象保留在内存

回收不可达引用对象的内存

  GC 解决了大部分的内存分配问题,它本身也占用一定的资源。当堆满了或者是它的某个组成部分达到一个阀值就会触发垃圾回收。垃圾回收主要从这几方面考虑:回收的频率和时间,比如堆小那么回收的次数就多,堆大回收次数少,但回收一次的时间长;内存碎片问题;多线程程序下的垃圾回收。

垃圾回收策略:

(1)串行与并行(Serial versus Parallel)

  串行,同一时间只能有一个垃圾回收线程工作;并行,在多CPU系统中,可有多个垃圾回收线程同时工作。

(2)并发与Stop-the-world(Concurrent versus Stop-the-world)

  Stop-the-world 垃圾回收器,在回收期间,应用程序完全暂停工作,此时堆就相当于被冻结了,对象的状态不可变;并发,一个或多个垃圾收集任务与应用程序同时执行,可能会出现短暂的Stop-the-world,在收集时,对象的状态可能会改变。

(3)复制(Copying)

  将内存分为两半,回收时将存活的对象复制到另一半空间,然后清除当前内存,后续内存的分配比较容易,但内存的利用率比较低。

(4) 标记清除与标记整理(Compacting versus Non-compacting)

  标记清除,标记可回收的对象,统一进行回收,不进行内存压缩,会产生大量的内存碎片,在分配大对象时,可能无法找到连续的内存;标记整理,在标记完后,首先对内存进行压缩整理,把所有存活的对象放到一起进行回收。

(5)分代收集

  把堆分成几个区域,新生代和老年代,不同的区域使用上面的不同的回收方法。

2.2 HotSpot 中的分代收集

  在 HotSpot 中,把内存分为新生代和老年代,新生代又分为Eden和两个大小一样的Survivor空间,大部分对象在Eden分配,一些大对象可能直接分配到老年代。

堆的结构如下:

t0128f824aa7ed65fdd.png

图 2 堆

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Adakah perisian keselamatan syarikat menyebabkan aplikasi gagal dijalankan? Bagaimana cara menyelesaikan masalah dan menyelesaikannya? Adakah perisian keselamatan syarikat menyebabkan aplikasi gagal dijalankan? Bagaimana cara menyelesaikan masalah dan menyelesaikannya? Apr 19, 2025 pm 04:51 PM

Penyelesaian masalah dan penyelesaian kepada perisian keselamatan syarikat yang menyebabkan beberapa aplikasi tidak berfungsi dengan baik. Banyak syarikat akan menggunakan perisian keselamatan untuk memastikan keselamatan rangkaian dalaman. …

Bagaimana dengan elegan mendapatkan nama pemboleh ubah kelas entiti untuk membina keadaan pertanyaan pangkalan data? Bagaimana dengan elegan mendapatkan nama pemboleh ubah kelas entiti untuk membina keadaan pertanyaan pangkalan data? Apr 19, 2025 pm 11:42 PM

Apabila menggunakan Mybatis-Plus atau Rangka Kerja ORM yang lain untuk operasi pangkalan data, sering diperlukan untuk membina syarat pertanyaan berdasarkan nama atribut kelas entiti. Sekiranya anda secara manual setiap kali ...

Bagaimana untuk memudahkan isu pemetaan medan dalam dok sistem menggunakan mapstruct? Bagaimana untuk memudahkan isu pemetaan medan dalam dok sistem menggunakan mapstruct? Apr 19, 2025 pm 06:21 PM

Pemprosesan pemetaan medan dalam dok sistem sering menemui masalah yang sukar ketika melaksanakan sistem dok: bagaimana untuk memetakan medan antara muka sistem dengan berkesan ...

Bagaimanakah Idea IntelliJ mengenal pasti nombor port projek boot musim bunga tanpa mengeluarkan log? Bagaimanakah Idea IntelliJ mengenal pasti nombor port projek boot musim bunga tanpa mengeluarkan log? Apr 19, 2025 pm 11:45 PM

Mula musim bunga menggunakan versi IntelliJideaultimate ...

Bagaimanakah saya menukar nama kepada nombor untuk melaksanakan penyortiran dan mengekalkan konsistensi dalam kumpulan? Bagaimanakah saya menukar nama kepada nombor untuk melaksanakan penyortiran dan mengekalkan konsistensi dalam kumpulan? Apr 19, 2025 pm 11:30 PM

Penyelesaian untuk menukar nama kepada nombor untuk melaksanakan penyortiran dalam banyak senario aplikasi, pengguna mungkin perlu menyusun kumpulan, terutama dalam satu ...

Bagaimana cara menukar objek Java dengan selamat ke array? Bagaimana cara menukar objek Java dengan selamat ke array? Apr 19, 2025 pm 11:33 PM

Penukaran objek dan tatasusunan Java: Perbincangan mendalam tentang risiko dan kaedah penukaran jenis cast yang betul Banyak pemula Java akan menemui penukaran objek ke dalam array ...

Bagaimana cara menukar nama ke nombor untuk melaksanakan penyortiran dalam kumpulan? Bagaimana cara menukar nama ke nombor untuk melaksanakan penyortiran dalam kumpulan? Apr 19, 2025 pm 01:57 PM

Bagaimana cara menukar nama ke nombor untuk melaksanakan penyortiran dalam kumpulan? Apabila menyusun pengguna dalam kumpulan, sering kali perlu menukar nama pengguna ke dalam nombor supaya ia boleh berbeza ...

Bagaimana menggunakan penyelesaian cache Redis untuk merealisasikan keperluan senarai kedudukan produk dengan cekap? Bagaimana menggunakan penyelesaian cache Redis untuk merealisasikan keperluan senarai kedudukan produk dengan cekap? Apr 19, 2025 pm 11:36 PM

Bagaimanakah penyelesaian caching Redis menyedari keperluan senarai kedudukan produk? Semasa proses pembangunan, kita sering perlu menangani keperluan kedudukan, seperti memaparkan ...

See all articles