JVM内存管理------JAVA语言的内存管理概述

转载自  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 a=9这句话来说,就需要先将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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328161.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软市值今天涨了 250 亿,这家离我们越来越远的公司,为什么生意反倒越来越好了?

纳德拉上台两年半,微软市值已经涨了 50% 今天早上,微软发布了今年第三季度的财报。受云计算和 Office 业务推动,财报后的盘后交易里,微软股价上涨 5.9%、市值涨了超过 250 亿美元——收购 LinkedIn 的钱差不多就回来了。 财报发布…

系统架构设计师考试 重要的部分

系统架构师考试比较的难,属于软件工程师考试中的高级考试,有选择题,分析题,论文,请坚持。 这是高产似母猪啊。 1.每天2小时,坚持了4年考过了软件设计师,系统架构师, 四年时间花了大…

计算机文化基础分析总结,《计算机文化基础实训》教学方案设计与课题分析总结.doc...

《计算机文化基础实训》教学方案设计与课题分析总结.doc《计算机文化基础一实训》教学方案设计与课题分析总结袁良风[ 】我院自开展木课题研宄工作以来,紧紧围绕“项目教学法”教学的应 用问题,积极主动地开展专题研究和教改实验,…

Oracle数据库基本概念理解(2)

--删除用户 drop user sz cascade; --创建表空间 create tablespace worktablsp datafile C:\app\lenovo\oradata\orcl\EMPTB.dbf SIZE 5MAUTOEXTEND ON; --修改表空间 ALTER tablespace worktablsp ADD datafile C:\app\lenovo\oradata\orcl\EMPTB.dbf SIZE 5M;--扩展数据文件…

Java中关于String类型的10个问题

转载自 Java中关于String类型的10个问题1. 如何比较两个字符串?用“”还是equals 简单来说,“”是用来检测俩引用是不是指向内存中的同一个对象,而equals()方法则检测的是两个对象的值是否相等。只要你想检测俩字符串是不是相等的&#xff…

[ASP.NET Core] Static File Middleware

前言 本篇文章介绍ASP.NET Core里,用来处理静态档案的Middleware,为自己留个纪录也希望能帮助到有需要的开发人员。 ASP.NET Core官网 结构 一个Web站台最基本的功能,就是在接收到从「浏览器传入」的HTTP Request封包后,将站台内所…

JVM 优化经验总结

转载自 JVM 优化经验总结开始之前 Java 虚拟机有自己完善的硬件架构, 如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 Java 虚拟机上运行的目标代码 (字节码), 就可以在多种平台上不…

2016年10月20日 .NET Core 1.0.2 更新

我们今天发布了一个更新,解决了在macOS Sierra系统上安装的问题。 更改仅限于macOS安装程序。 运行时或工具没有更改; .NET Core 1.0.1仍是Windows和Linux的最新版本,最新的Microsoft.NETCore.App版本仍为1.0.1。 您现在可以下载更新的.NET Core 1.0.2 m…

window7连接其他计算机的打印机,win7系统电脑怎样连接其它电脑上在打印机?

2017-12-02 回答方法/步骤1第一步:设置共享打印机电脑。(a电脑)单击【开始】-【设备和打印机】或点击【开始】/【控制面板】/【硬件和声音】/【设备和打印机】,打开【添加设备】和【添加打印机】窗口,如图1所示2设置要共享的打印机&#xff0…

系统架构设计师考试999999999999

系统架构师考试比较的难,属于软件工程师考试中的高级考试,有选择题,分析题,论文,请坚持。 这是高产似母猪啊。 1.每天2小时,坚持了4年考过了软件设计师,系统架构师, 四年时间花了大…

Java启动参数与内存调优一些学习笔记

转载自 Java启动参数与内存调优一些学习笔记 .参数的含义-Xms128m JVM初始分配的堆内存 -Xmx512m JVM最大允许分配的堆内存,按需分配 -XX:PermSize64M JVM初始分配的非堆内存 -XX:MaxPermSize128M JVM最大允许分配的非堆内存,按需分配 JVM内存模型 …

Oracle数据库基本概念理解(3)

/*| PL/SQL编程*/ --声明变量 DECLAREV_NAME VARCHAR2(20); --一般变量V_AGE NUMBER(2);v_id SUN.TUSER.USERID%TYPE:14;--属性变量v_user SUN.TUSER%ROWTYPE; --行属性变量 BEGIN--赋常量值V_NAME:Tom;V_AGE :20;DBMS_OUTPUT.put_line(姓名:||V_NAME||年…

服务器io修改,更改 Linux I/O 调度器来改善服务器性能

为了从 Linux 服务器榨取尽可能多的性能,请了解如何更改 I/O 调度器以满足你的需求。Linux I/O 调度器()控制内核提交读写请求给磁盘的方式。自从 2.6 内核以来,管理员已经能够更改这个调度器,所以他们可以自定义他们的平台以完全适合他们的需…

如何合理的规划一次 JVM 性能调优

转载自 如何合理的规划一次 JVM 性能调优摘要: JVM性能调优涉及到方方面面的取舍,往往是牵一发而动全身,需要全盘考虑各方面的影响,那么如何进行一次优雅的调优,提升应用的性能?这是 JVM 优化系列第三篇:JVM 调优系列…

服务器复制不了文档,服务器复制粘贴不了

服务器复制粘贴不了 内容精选换一换帮助用户完成专属云服务器备份任务的创建,快速完成服务器数据保护。专属云服务器不支持应用一致性备份。当专属对象存储的容量不足时,会导致专属云服务器备份创建失败。已开通专属对象存储。登录管理控制台。单击&…

大神开发的模板框架 包括常见的功能

https://gitee.com/lcg0124/bootdo http://localhost/ 就可以访问了 http://localhost/blog

在Linux开发.NET——拜拜了Win10

我是一个有多年开发经验的.NET程序员。最近,我决定使用*NIX系统来开发.NET程序,虽然看起来有些激进,但是我可以说,这是我做过最好的决定了。 事情的起因是这样的,上周星期五(十月14日)&#xff…

20个非常有用的Java程序片段

转载自 20个非常有用的Java程序片段下面是20个非常有用的Java程序片段,希望能对你有用。 1. 字符串有整型的相互转换String a String.valueOf(2); //integer to numeric string int i Integer.parseInt(a); //numeric string to an int 2. 向文件末尾添加内…

从工程转向管理,访谈Github公司的Phil Haack

在本次播客中,QCon旧金山大会、 伦敦大会和纽约大会的主席Wes Reisz访谈了GitHub的工程主管Phil Haack,Haack在Github的工作聚焦于实现将软件推送到开发人员的桌面,当前正致力于发布GitHub Desktop这样的软件。GitHub Desktop是用于Visual St…