首页 > 系统相关 >《深入理解Java虚拟机》读书笔记:Java内存区域

《深入理解Java虚拟机》读书笔记:Java内存区域

时间:2023-08-03 18:44:38浏览次数:37  
标签:Java 读书笔记 虚拟机 计数器 线程 内存 方法

Java内存区域包含程序计数器、虚拟机栈、本地方法栈、Java堆、方法区五个区域。

运行时数据区分类

 

Java内存区域

 

一、程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的信号指示器。

字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。

 

二、Java虚拟机栈

Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

  • 局部变量表

局部变量表存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。

可能的异常

在Java虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

 

三、本地方法栈

本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。

 

四、 Java堆

Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。所有的对象实例以及数组都要在堆上分配。

可能的异常

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

 

五、方法区

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

对于习惯在HotSpot虚拟机上开发、部署程序的开发者来说,很多人都更愿意把方法区称为“永久代”(Permanent Generation),本质上两者并不等价,使用永久代来实现方法区,现在看来并不是一个好主意,因为这样更容易遇到内存溢出问题(永久代有-XX:MaxPermSize的上限),而且有极少数方法(例如String.intern())会因这个原因导致不同虚拟机下有不同的表现。现在也有放弃永久代并逐步改为采用Native Memory来实现方法区的规划了。

  • 运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

 

六、直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现,所以我们放到这里一起讲解。

可能的异常

本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,肯定还是会受到本机总内存(包括RAM以及SWAP区或者分页文件)大小以及处理器寻址空间的限制。服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常。

标签:Java,读书笔记,虚拟机,计数器,线程,内存,方法
From: https://www.cnblogs.com/fhey/p/17604165.html

相关文章

  • 三个实例演示 Java Thread Dump 日志分析
    jstackDump日志文件中的线程状态dump文件里,值得关注的线程状态有:死锁,Deadlock(重点关注) 执行中,Runnable  等待资源,Waitingoncondition(重点关注) Waitingonmonitorentry(重点关注)暂停,Suspended对象等待中,Object.wait()或TIMED_WAITING阻塞,Blocked(重点关注)......
  • 使用windows访问另一台windows中的vmware虚拟机
    使用windows访问另一台windows中的vmware虚拟机一、场景描述在平常的学习中,当我们的设备较多且都为windows设备时,通常会遇到在一台windows中需要访问另一台windows上的虚拟机,需求如图:二、问题分析首先我们的两台windows之间是可以正常通信的windows与vm是可以正常通信的......
  • java爱心代码,脱单必备
    packagecom.example.test;importjava.awt.Color;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.Image;importjava.awt.Toolkit;importjava.util.jar.JarOutputStream;importjavax.swing.JFrame;classCardioidextendsJFrame{//定义窗口大小privatestat......
  • JavaScript基础04
    函数函数定义function自定义函数名(){ 函数体代码;}//函数名命名:1.与变量名规则基本上是一样的!2.建议变量名使用名词,函数名用动词3.大小写敏感4.普通函数使用小驼峰,不要首字母大写5.首字母大写的函数一般用作自定义构造函数函数调用自定义函数名();匿名......
  • 学习Java第13天
    逻辑运算符packageoperator;//**逻辑运算符publicclassDemo05{publicstaticvoidmain(String[]args){//**与(**and)或(or)**非(取反)booleana=true;booleanb=false;System.out.println("a&&b:"+(a&&b));//*逻辑与运算:两个变量都为真,结果才为true**......
  • vmware中克隆虚拟机无法上网的解决办法
    1、首先编辑网卡配置文件,vi/etc/sysconfig/network-scripts/ifcfg-eth0,将HWADDR和UUID两个参数删除或者注释掉,然后保存退出。2、清空/etc/udev/rules.d/70-persistent-net.rules文件,>/etc/udev/rules.d/70-persistent-net.rules3、重启虚拟机 ......
  • java加参数jar
    加参数启动jenkins nohupjava-Xmx3096m-Xms3096m-DHUDSON_HOME=/data/ci/jspace-jar/data/ci/jenkins.war --httpPort=port--ajp13Port=port&加参数启动中间件 java -XXXXX.jar“-Xmx1024m-Xms1024m-Xmn512m-Xss256k”——Java运行参数(转)年轻代年老代概念......
  • Java计算CRC16校验码
    废话不多说,直接上代码/***计算CRC16校验码**@parambytes需要计算的字节数组*/publicstaticbyte[]getCRCByteArray(byte[]bytes){//ModBus通信协议的CRC(冗余循环校验码含2个字节,即16位二进制数。//......
  • Java入门题-百钱买百鸡
    题:100钱买100只鸡,必须满足,钱花完,鸡百只 重点:循环语句来枚举所有可能性 代码:byteplan=1;for(inti=0;i<20;i++){for(inti1=0;i1<34;i1++){for(inti2=0;i2<101;i2++){if(((i*5+i1*3+i2)==100)&&((i+i1......
  • 基于JAVA的博客平台设计与实现
    随着互联网技术的快速发展,利用博客平台实现用户资讯的发布管理成为很多互联网公司研究的热门话题。通过对博客平台系统的网站功能需要进行讨论研究,这种资讯发布非常符合资讯发展的潮流,博客平台的实现将会对当前网站的信息推广产生不可估量的巨大浏览提升。正是鉴于此种对潜在用户主......