深圳网站搭建多少钱,公司网站宣传,杭州市建设信用网网站,平台推广是做什么转载自 JVM内存管理------JAVA语言的内存管理概述引言 内存管理一直是JAVA语言自豪与骄傲的资本#xff0c;它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节#xff0c;只专注于业务逻辑。不过世界上不存在十全十美的好事#xff0c;在带来了便利的同时#xf…转载自 JVM内存管理------JAVA语言的内存管理概述引言 内存管理一直是JAVA语言自豪与骄傲的资本它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节只专注于业务逻辑。不过世界上不存在十全十美的好事在带来了便利的同时也因此引入了很多令人抓狂的内存溢出和泄露的问题。可怕的事情还不只如此有些使用其它语言开发的程序员给JAVA程序员扣上了一个“不懂内存”的帽子这着实有点让人难以接受。毕竟JAVA当中没有malloc和delete、没有析构函数、没有指针刚开始接触JAVA的程序员们又怎么可能接触内存这一部分呢更何况有不少JAVA程序员还是跳了专业半路出家的朋友。不过事实尽管难以接受但也确实有不少JAVA程序员对内存这部分可谓一窍不知尽管掌握内存的相关知识或许并不能给平时的开发带来翻天覆地的变化和好处不过它仍然会潜移默化的提高你的技术水准这一点在了解完内存管理之后相信各位就会深有体会了。内存划分谈到内存这一词汇它是在程序运行时才有的数据存储区域而对于这一块区域的划分各个虚拟机有各自的划分方式不过它们都必须遵从JAVA虚拟机的基本规范去实现。虚拟机规范中将内存划分为六大部分分别是PC寄存器、JAVA虚拟机栈、JAVA堆、方法区、运行时常量池以及本地方法栈。JAVA虚拟机规范与JAVA虚拟机这里还需要解释一下JAVA虚拟机规范和JAVA虚拟机的区别顾名思义JAVA虚拟机规范是一种对JAVA虚拟机实现的规范要求是由oracle制定的而我们平时常说的JAVA虚拟机一般是指的一种具体的JAVA虚拟机规范的实现。比如我们最经常使用的JAVA虚拟机hotspot其实JAVA虚拟机还有很多种实现甚至如果你对JAVA虚拟机规范有了深入的了解而且对此有兴趣的话可以写一个自己的JAVA虚拟机当然这其中的难度不难想象。结构图下图是引用于百度文库的一张JVM的结构图由于运行时常量池是由方法区分配出来的区域所以此图当中没有运行时常量池。内存区域详解针对上面这张图内存就是指的矩形框当中运行期数据区这部分下面简单介绍一下各个部分的作用1、PC寄存器线程独有全称是程序计数寄存器它记载着每一个线程当前运行的JAVA方法的地址如果是当前执行的是本地方法则程序计数器会是一个空地址。它的作用就是用来支持多线程线程的阻塞、恢复、挂起等一系列操作直观的想象一下要是没有记住每个线程当前运行的位置又如何恢复呢。依据这一点每一个线程都有一个PC寄存器也就是说PC寄存器是线程独有的。2、JAVA虚拟机栈线程独有JAVA虚拟机栈是在创建线程的同时创建的用于存储栈帧JAVA虚拟机栈也是线程独有的。
栈帧简单点说可以解释为是一个方法运行时临时数据的存储区域具体点说它里面包括了数据和部分的过程结果与此同时它又肩负着处理方法返回值、动态链接以及异常分派的任务。栈帧是随着方法的创建而创建随着方法的结束而销毁如果方法抛出异常也算方法结束。然而在每一个栈帧中都有着自己的局部变量表以及操作数栈以及对当前类的运行时常量池的引用。局部变量表它是一个方法局部变量的列表是在编译时期就写入了class文件当中。简单的理解可以将它理解为一个对象数组而里面按照索引0到length-1分别对应于每一个局部变量特别的如果是实例方法的局部变量表第0个局部变量会是一个指向当前实例的引用也就是this关键字其余的局部变量则从索引1开始。操作数栈它是一个后进先出LIFO栈而它的长度也是在编译时期就写入了class文件当中是固定的。它的作用就是提供字节码指令操作变量计算的空间比如简单的对于int a9这句话来说就需要先将9压入操作数栈再将9赋给a这个变量。3、JAVA堆全局共享这一部分是JAVA内存中最重要的一部分之所以说是最重要的一部分并不是因为它的重要性而是指作为开发人员最应该关注的一部分。它随着JAVA虚拟机的启动创建储存着所有对象实例以及数组对象而且内置了“自动内存管理系统”也就是我们常说的垃圾搜集器GC。JAVA堆中的内存释放是不受开发人员控制的完全由JAVA虚拟机一手操办。对于JAVA虚拟机如何实现垃圾搜集器JAVA虚拟机规范没有明确的规定也正因如此我们平时使用的JAVA虚拟机中提供了许多种垃圾搜集器它们采用不同的算法以及实现方式已满足多方面的性能需求。4、方法区全局共享方法区也是堆的一个组成部分它主要存储的是运行时常量池、字段信息、方法信息、构造方法与普通函数的字节码内容以及一些特殊方法。它与JAVA堆的区别除了存储的信息与JAVA堆不一样之外最大的区别就是这一部分JAVA虚拟机规范不强制要求实现自动内存管理系统GC。5、本地方法栈线程独有本地方法栈是一个传统的栈它用来支持native方法的执行。如果JAVA虚拟机是使用的其它语言实现指令集解释器的时候也会用到本地方法栈。如果前面这两种都未发生也就是说如果JAVA虚拟机不依赖于本地方法栈而且JAVA虚拟机也不支持native方法则不需要本地方法栈。而如果需要的话则本地方法栈也是随每一个线程的启动而创建的。上面五个内存区域除了PC寄存器之外其余四个一般情况下都要求JAVA虚拟机实现提供给客户调节大小的参数也就是我们常用的Xms、Xmx等等。内存管理内存管理分为内存分配和内存释放看一下上面的五个内存区域其实可以大致分为两部分一部分是全局共享一部分是线程独有。对于线程独有的这部分内存都是随着线程的启动而创建而当线程被销毁时内存也就随之释放。这一部分内存不需要垃圾搜集器的管理而是JAVA虚拟机来主动管理每当一个线程被创建的时候JAVA虚拟机就会为其分配相应的PC寄存器和JAVA虚拟机栈如果需要的话还会有本地方法栈。相应的当一个线程被销毁的时候JAVA虚拟机也会将这个线程所占有的内存全部释放。相对于线程独有的那部分内存全局共享的这部分内存更加难以处理不过这只是针对于虚拟机的实现来说因为这一部分内存是要实现自动内存管理系统GC的。全局共享的这部分内存以下简称堆内存分配主要是由程序员显示的使用new关键字来触发的至于new出来的这部分内存在哪分配如何分配则是JAVA虚拟机来决定。而这部分内存的释放则是由自动内存管理系统以下简称GC来管理的。通常情况下堆内存分配是要依赖于GC的策略与实现的在分配的时候就要考虑好到时候如何回收这部分内存。也是正因为如此对于内存分配这一部分的讲解来说我们必须得先了解内存是如何被回收的才能更好的理解内存要怎么被分配。结束语本次对于JAVA语言中内存管理的概述就到此结束了接下来的章节会着重讲解一下GC的原理以及实现方式请各位敬请期待吧。本章内容主要参考资料《The JavaTM Virtual Machine Specification》地址http://docs.oracle.com/javase/specs/jvms/se5.0/html/VMSpecTOC.doc.html