您好、欢迎来到现金彩票网!
当前位置:老k棋牌 > 栈机制 >

jvm-内存管理机制(一)

发布时间:2019-06-27 08:01 来源:未知 编辑:admin

  JVM内存区域主要包括如下部分:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。

  JVM内存管理也可以理解为–jvm运行时数据区,jvm内存主要管理的就是这片内存区域。

  java的堆是一个运行时的数据区,用来存储数据的单元,存放通过new关键字新建的对象和数组,对象从中分配内存。

  在堆中声明的对象,是不能直接访问的,必须通过在栈中声明的指向该引用的变量来调用。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

  java虚拟机所管理的内存中最大的一块。java堆时被所有线程共享的一块内存区域,在虚拟机启动时创建。

  此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。(几乎所有的对象实例以及数组都要在堆上分配。

  java堆中还细分为:新生代,老年代;再细分一点有Eden空间,From Survivor(sərˈvaɪvə(r),幸存者)空间,To Survivor空间

  各线程共享区域,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

  类信息有:每个类的全限定名、每个类的直接超类的全限定名、该类是类还是接口、该类型的访问修饰符、直接超接口的全限定名的有序列表。

  每个已装载类的详细信息:运行时常量池、字段信息、方法信息、静态变量、到类classloader的引用、到类class的引用。

  运行时常量池:在方法区中,每个类型都对应一个常量池,存放该类型所用到的所有常量,常量池中存储了诸如文字字符串、final变量值、类名和方法名常量。

  字段信息:字段信息存放类中声明的每一个字段的信息,包括字段的名、类型、修饰符。

  字段名称:指的是类或接口的实例变量或类变量,字段的描述符是一个指示字段的类型的字符串,如private A a=null;则a为字段名,A为描述符,private为修饰符

  方法信息:类中声明的每一个方法的信息,包括方法名、返回值类型、参数类型、修饰符、异常、方法的字节码。

  (在编译的时候,就已经将方法的局部变量、操作数栈大小等确定并存放在字节码中,在装载的时候,随着类一起装入方法区。)

  静态变量:就是类变量,类的所有实例都共享,在方法区有个静态区,静态区专门存放静态变量和静态块。

  到类class 的引用:虚拟机为每一个被装载的类型创建一个class 实例,用来代表这个被装载的类。

  所谓静态常量池 ,即*.class文件中的常量池。class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,它们占用class文件绝大部分空间。

  而运行时常量池 ,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区 中,我们常说的常量池,就是指方法区中的运行时常量池。

  运行时常量池(Constant Pool Table),用于存放编译期生成的各种字面量、符号引用,String字符串、final变量值、类和结构的完全限定名,方法的名称和描述符,字段的名称和描述符,这部分内容将在类加载后存放到方法区的运行时常量池中。它们以数组形式通过索引被访问,是外部调用与类联系及类型对象化的桥梁.

  在运行时,JVM从常量池中获得符号引用,然后在运行时解析成引用项的实际地址,最后通过常量池中的全限定名、方法和字段描述符,把当前类或接口中的代码与其它类或接口中的代码联系起来。

  程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池。

  运行时常量池除了存放编译期产生的Class文件的常量外,还可存放在程序运行期间生成的新常量,比较常见增加新常量方法有String类的internd()方法。ern()是一个Native方法,它的作用是:如果运行时常量池中已经包含一个等于此String对象内容的字符串,则返回常量池中该字符串的引用;如果没有,则在常量池中创建与此String内容相同的字符串,并返回常量池中创建的字符串的引用。不过JDK7的intern()方法的实现有所不同,当常量池中没有该字符串时,不再是在常量池中创建与此String内容相同的字符串,而改为在常量池中记录堆中首次出现的该字符串的引用,并返回该引用。

  由于运行时常量池在方法区中,我们可以通过jvm参数:-XX:PermSize、-XX:MaxPermSize来设置方法区大小,从而间接限制常量池大小。

  但是,JDK1.7之前运行时常量池是方法区的一部分,JDK1.7及之后版本已经将运行时常量池从方法区中移了出来,在堆(Heap)中开辟了一块区域存放运行时常量池。

  绝大部分 Java 程序员应该都见过 “g.OutOfMemoryError: PermGen space “这个异常。这里的 “PermGen space”其实指的就是方法区。不过方法区和“PermGen space”又有着本质的区别。前者是 JVM 的规范,而后者则是 JVM 规范的一种实现,并且只有 HotSpot 才有 “PermGen space”,而对于其他类型的虚拟机,如 JRockit(Oracle)、J9(IBM) 并没有“PermGen space”。由于方法区主要存储类的相关信息,所以对于动态生成类的情况比较容易出现永久代的内存溢出。

  - 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。

  每个方法在执行的同时都会创建一个栈帧用于存储局部变量,操作数栈,动态链接,方法出口等信息,每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程

  为一个以字为单位的数组,每个数组元素对应一个局部变量的值。调用方法时,将方法的局部变量组成一个数组,通过索引来访问。若为非静态方法,则加入一个隐含的引用参数this,该参数指向调用这个方法的对象。而静态方法则没有this参数。因此,对象无法调用静态方法。

  也是一个数组,但是通过栈操作来访问。所谓操作数是那些被指令操作的数据。当需要对参数操作时如a=b+c,就将即将被操作的参数压栈,如将b 和c 压栈,然后由操作指令将它们弹出,并执行操作。虚拟机将操作数栈作为工作区。

  如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出stackoverflowError;如果虚拟机可以动态扩展,但是无法申请到足够的内存时,就会抛出outOfMemoryError异常。

  ,栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈,至于采用的存储方式(实现方式)是顺序存储(顺序栈)还是链式存储(链式栈)是没有关系的。堆则是二叉树的一种,有最大堆最小堆,排序算法中有常用的堆排序。

  ,栈是系统为运行的程序分配的先进后出的存储区域。在执行函数时,函数内部局部变量的存储单元可以在栈上创建(针对CISC架构而 言,RISC架构下,局部变量的存储单元是在寄存器上创建),函数执行结束时这些存储单元自动被释放。堆是系统管理的可以被程序利用的全局存储空间,动态 内存分配就是从堆上分配。现在计算机(串行执行机制),都直接在代码层次支持栈这种数据结构。这体现在,有专门的寄存器指向栈所在的地址,

  。比如ARM指令中的stmfd和ldmfd。因为栈内存分配运算内置于处理器的指令集中,所以效率很高,但是支持的数据有限,一般是整数、指 针、浮点数等系统直接支持的数据类型,并不直接支持其他的数据结构。和栈不同,堆的数据结构并不是由系统(无论是机器系统还是操作系统)支持的,而是由函数库提供的。

  栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而堆是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。

  栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一,不同堆分配的内存无法互相操作。

  栈空间分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloc函数完成。栈的动态分配无需释放 (是自动的),也就没有释放函数。为可移植的程序起见,栈的动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放 回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。

  stack:由系统自动分配,速度较快。但程序员是无法控制的。heap:由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

  看了堆和栈的介绍,堆和栈都是内存,就好比一张桌子里面有两个抽屉,一个抽屉里面存放一种东西,另外一个抽屉存放另一种东西,这样方便存取方便,找东西也比较快捷方便。

  堆的地址空间是从低到高存储,栈的地址空间是从高到底存储。(就是一个小区,有100栋楼,堆从1-100开始分房子;而栈是从100到1分房子)

  局部变量,操作数都是放在栈里面的,使用时入栈占用栈内存空间,时候完毕后出栈释放栈内存空间;堆则不一样,new关键字有程序自己分配内存空间,使用完毕后自己回收空间垃圾值。

  注意:每个线程都有自己的栈空间哦;所以多线程的时候栈是不用担心的,栈是线程私有的,不存在线程安全问题。

  顺带讲一下高低位上面说的堆和栈的高低位是地址空间的高低位,就是楼层编号一样。这里讲的高低位则是字节序的高低位,是不一样的哦。在汇编指令中,刚开始的cpu是16位的,分为高8位,低8位,分别用AH,AL指令操作高,低位。AH直接指向高位地址,Al直接指向低8位地址。

  后来CPU支持32位了,为了向下兼容,32位的高位用EAX表示,那么64位的CPU呢?64位的高位还没有相应的指令,所以64位的二进制字节序取值需要使用位运算,向右移位操作。高低位的区分只是为了存取方便和读取效率高。

  转载请注明出处:     在上一篇blog中介绍过POI检索的使用,本篇blog主要介绍公交信息检索和线路规划的内容。 公交信息检索     实际上,公交信息检索与POI检索、在线建议检索非常相似,也...博文来自:

  Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的Thread...博文来自:

  C#实现开发windows服务实现自动从FTP服务器下载文件(自行设置分/时执行)

  最近在做一个每天定点从FTP自动下载节目.xml并更新到数据库的功能。首先想到用 FileSystemWatcher来监控下载到某个目录中的文件是否发生改变,如果改变就执行相应的操作,然后用timer...博文来自:

  摘要 最近要发论文了,被知乎里人推荐使用论文编译软件(CTex、LaTex和Overleaf之类),瞬间感觉自己用Word简直Out了(书读少)。 学校里也听说过LaTex,不过因为当时没怎么写过...博文来自:

  看到很多朋友配置vsftpd时不能使用匿名用户上传和下载(创建目录或删除、重命名文件夹),本文主要解决vsftpd的匿名用户权限配制问题。...博文来自:

  一个例子高斯混合模型(Gaussian Mixed Model)指的是多个高斯分布函数的线性组合,理论上GMM可以拟合出任意类型的分布,通常用于解决同一集合下的数据包含多个不同的分布的情况(或者是同一...博文来自:

  最近比较有空,大四出来实习几个月了,作为实习狗的我,被叫去研究Docker了,汗汗! Docker的三大核心概念:镜像、容器、仓库 镜像:类似虚拟机的镜像、用俗话说就是安装文件。 容器:类似一个轻量...博文来自:

  本篇文章是根据我的上篇博客,给出的改进版,由于时间有限,仅做了一个简单的优化。相关文章:将excel导入数据库2018年4月1日,新增下载地址链接:点击打开源码下载地址十分抱歉,这个链接地址没有在这篇...博文来自:

  Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且...博文来自:

  三菱FX系列PLC与PC通讯的实现之专有协议(计算机联接)的程序设计之一

  阅读内容为:FX系列微型可编程控制器用户手册(通讯篇)中计算机链接功能章节。 采用本方法通信,pc端的实现,其实就是,把操作按照协议(2种)翻译成相应的字符串,通过串口发送给plc。 编写一应用程...博文来自:

  强连通分量: 简言之 就是找环(每条边只走一次,两两可达) 孤立的一个点也是一个连通分量   使用tarjan算法 在嵌套的多个环中优先得到最大环( 最小环就是每个孤立点)   定义: int Ti...博文来自:

  这几天开始研究linux下的驱动程序编写了,遇到的问题也挺多的,好在linux是开源的,很多高人编写的技巧和思路都会在他们的源代码中体现,我也在他们的源码中学到了很多好东西,我归纳了下贴出来,希望自己...博文

  苹果充值的刷单现象在游戏行业非常普遍,很多团队挖空心思寻找漏洞以非法获利。常见的手段主要有以下六种: 伪造充值凭据(receipt)以小额凭据骗取大额商品 凭据重复使用 凭据重复使用信用卡黑卡/...博文来自:

  jquery/js实现一个网页同时调用多个倒计时(最新的) 最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦! //js ...博文来自:

  一、代理模式为某个对象提供一个代理,从而控制这个代理的访问。代理类和委托类具有共同的父类或父接口,这样在任何使用委托类对象的地方都可以使用代理类对象替代。代理类负责请求的预处理、过滤、将请求分配给委托...博文来自:

  如下图所示,蜂窝小区,以1为中心,顺时针编号,编号最大限定为100000。求任意两编号之间的最短距离。两个相邻小区的距离为1 示例:19到30的最短距离为5 实现如下三个接口: /**********...博文来自:

  在MATLAB中,可以注释一段程序。 使用“%{”和“%}”。 例如 %{ 。。。 %} 即可。 经典方法是用 if 0,但缺点是不够直观,注释掉的内容仍然保持代码的颜色。现在可以用 ...博文来自:

http://theenigmaco.com/zhanjizhi/142.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有