Java运行时内存

  对于java程序员来说,并不必显示地对内存进行管理,一切都交给java虚拟机去做吧,而且,你也不一定做得比java虚拟机来得专业。好像所有内存管理都交给虚拟机去做就万事大吉了,但是,事实有时并非如此,可能有时你会遇到一些让你困惑的问题,如OutOfMemoryError异常,如stackOverflowError,你开始大呼,虚拟机不是都为我们管理好内存了吗?怎么还会出现这样的Error,其实当你真正去了解java虚拟机内存区域的分布的时候,你就会不自觉的大呼:原来java虚拟机也不是万能。

这是从网上找到的一个java运行时数据区域,主要包括了方法区(Method Area),java栈区(java stack),本地方法栈区(native method),堆(heap)和程序计数器(program counter register),其中,和java垃圾回收器打交道最多的就是堆了,下面我们就它们的作用分别简述一下:

在这之前,首先要介绍一下什么是本地方法:

 

1.程序计数器(Program Counter Register):

  每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令,对于非Native方法,这个区域记录的是正在执行的VM原语的地址,如果正在执行的是Natvie方法,这个区域则为空(undefined)。此内存区域是唯一一个在VM Spec中没有规定任何OutOfMemoryError情况的区域。

2.Java虚拟机栈(Java Virtual Machine Stacks)

  与程序计数器一样,VM栈的生命周期也是与线程相同。VM栈描述的是Java方法调用的内存模型:每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储局部变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。

     局部变量表存放了编译期间就可知的基本数据类型(boolean byte ing char ****)、对象引用等,在编译期间内存空间是已经分配好的,当进入一个方法需要在这其中分配多大的内存是已经完全确定的,在方法运行期间局部变量表是不可改变的。

3.本地方法栈(Native Method Stacks)

  本地方法栈与VM栈所发挥作用是类似的,只不过VM栈为虚拟机运行VM原语服务,而本地方法栈是为虚拟机使用到的Native方法服务。它的实现的语言、方式与结构并没有强制规定,甚至有的虚拟机(譬如Sun Hotspot虚拟机)直接就把本地方法栈和VM栈合二为一。和VM栈一样,这个区域也会抛出StackOverflowError和OutOfMemoryError异常。

4、Java堆

  对于绝大多数应用来说,Java堆是虚拟机管理最大的一块内存。Java堆是被所有线程共享的,在虚拟机启动时创建。Java堆的唯一目的就是存放对象实例,绝大部分的对象实例都在这里分配。这一点在VM Spec中的描述是:所有的实例以及数组都在堆上分配(原文:The heap is the runtime data area from which memory for all class instances and arrays is allocated),但是在逃逸分析和标量替换优化技术出现后,VM Spec的描述就显得并不那么准确了。

  Java堆内还有更细致的划分:新生代、老年代,再细致一点的:eden、from survivor、to survivor,甚至更细粒度的本地线程分配缓冲(TLAB)等,无论对Java堆如何划分,目的都是为了更好的回收内存,或者更快的分配内存。

  根据VM Spec的要求,Java堆可以处于物理上不连续的内存空间,它逻辑上是连续的即可,就像我们的磁盘空间一样。实现时可以选择实现成固定大小的,也可以是可扩展的,不过当前所有商业的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。如果在堆中无法分配内存,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。上次我们做一个项目的时候,刚开始部署到服务器上的时候,总是出现OutOfMemoryError异常,后来发现,原来jdk1.6默认的堆空间最大是64M,后来我们通过把最大堆值设置大了,解决了这个问题,当然最大堆值不是越大越好,java中允许直接内存进行堆外分配,如果你把堆值设置太大了,那么当剩下的机器内存不足以直接内存的那部分程序使用的话,也会抛出OutOfMemoryError的异常。

5.方法区(Method Area)

  方法区中存放了每个Class的结构信息,包括常量池、字段描述、方法描述等等。VM Space描述中对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存,也可以选择固定大小或者可扩展外,甚至可以选择不实现垃圾收集。相对来说,垃圾收集行为在这个区域是相对比较少发生的,但并不是某些描述那样永久代不会发生GC(至少对当前主流的商业JVM实现来说是如此),这里的GC主要是对常量池的回收和对类的卸载,虽然回收的“成绩”一般也比较差强人意,尤其是类卸载,条件相当苛刻

6.运行时常量池(Runtime Constant Pool)

  Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表(constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池(最典型的String.intern()方法)。

  运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法在申请到内存时会抛出OutOfMemoryError异常。

7.本机直接内存(Direct Memory)

  直接内存并不是虚拟机运行时数据区的一部分,它根本就是本机内存而不是VM直接管理的区域。但是这部分内存也会导致OutOfMemoryError异常出现,因此我们放到这里一起描述。

  在JDK1.4中新加入了NIO类,引入一种基于渠道与缓冲区的I/O方式,它可以通过本机Native函数库直接分配本机内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显着提高性能,因为避免了在Java对和本机堆中来回复制数据。

  显然本机直接内存的分配不会受到Java堆大小的限制,但是即然是内存那肯定还是要受到本机物理内存(包括SWAP区或者Windows虚拟内存)的限制的,一般服务器管理员配置JVM参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),而导致动态扩展时出现OutOfMemoryError异常。

转载于:https://www.cnblogs.com/plxx/p/3712770.html

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

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

相关文章

中班机器人上课视频_家委会:出班费买智能扫地机器人,不用家长搞卫生了,莫名其妙...

【01】原来大家上学,几乎是很随意的样子,有人至没上过幼儿园,有的上过半年,然后就直接升小学。可即使是升小学了,家长也不会管,全凭自己了。可如今随着社会的发展,父母们都非常重视孩子们的学习…

Powerful Sleep(神奇的睡眠-睡眠生物钟的秘密:如何睡得更少却睡得更好)阅读笔记...

睡眠机制 我们活着的时候,大脑会产生脑电波。脑电图仪器通过贴在人头上的一些电极读出脑电波的活动,然后把活动用图表显示出来。 睡眠过程可以分为5个过程,划分依据与大脑发出的脑电波类型。 当人清醒时,大脑发出β脑电波&#xf…

ue4集合类型_UE4粒子系统渲染管线概述

本文基于UE4版本4.25.3,对Cascade粒子系统的移动端渲染管线进行简单的概括和描述。Game Thread部分粒子系统Actor被Spawn(或所在的Level被加载)的时候,UParticleSystemComponent注册和初始化,并通过CreateSceneProxy函…

ip反查MAC地址

打开DOS命令提示符窗口,在窗口中输入命令“nbtstat -a IP”,如以上面查到的“10.10.3.21”为例,输入“nbtstat -a 10.10.3.21”转载于:https://www.cnblogs.com/jtm789/p/3715535.html

2、Sprite,SpriteBatch,Texture,TextureRegion的初步认识

昨天搭建了环境,今天就初步接触这个4个控件(Sprite,SpriteBatch,Texture,TextureRegion) 1、SpriteBatch 这个吗,我没有看api文档,偶是直接看土豆的博客学习的,我看了代码…

nedc和epa续航里程什么意思_NEDC、WLTP和EPA续航里程哪种最真实,用车注意事项都有什么...

我的理解是:从目前来看,衡量一款新能源电动汽车的性能指标,其中最为关键的就是车辆的续航里程,而这个续航里程使用不同的测试方法又会有不同的表现。从现有的续航里程测试标准来看,主要有NEDC、WLTP、EPA三种方式&…

javascript系列之执行上下文

写在前面:一 直想系统的总结一下学过的javascript知识,喜欢这门语言也热爱这门语言。未来想从事前端方面的工作,提前把自己的知识梳理一下。前面写了些 DOM的知识,略觉水平有限。没几个月就要开赴找工作的前线,奈何自己…

linux系统在虚拟机中迁移的技术难点

linux系统在虚拟机迁移中的技术难点通常我们期望虚拟机的迁移能够全部自动化或者部分自动化完成,但实际上Linux系统在P2V(Physical to virtual 物理到虚拟)和V2V(virtual to virtual)的迁移中可能遇到一些困难。1.磁盘…

Altium Designer 09简易教程(一)

【写的不好请谅解】 1、首先需要先准备好软件,这个大家就直接去网上找一下,安装也不难,如果有需要也可以给我留言哈嘻嘻嘻; 2、打开ad09; 3、大家会发现整个界面都是英语,可能看起来有点累吧,就…

莒南机器人_莒南42项重点建设项目公布!一定有你关注的

10日,县发改局公布莒南县2020年重点建设项目表!涉及工业、服务业、基础设施、现代农业等行业,共42项。详↓工业1、山东钢铁集团永锋临港有限公司临港先进优特钢产业基地一期项目投资方:山东钢铁集团永锋临港有限公司建设地点&…

配置Mysql实现主从复制与读写分离

环境说明 主从复制使用mysql自带的master与slave机制;读写分离使用mysql-proxy实现! 有服务器三台:s1,s2,s3。 s1为web服务器,装有httpd,php,mysql,mysql-proxy。 s2为主数据库服务器&#xff0…

js两个小技巧【看到了就记录一下】

1、不声明第三个变量实现交换 var a1,b2; a[b,ba][0];//执行完这句代码之后 a的值为2 b的值为1了 2、&&和||的用法 (学会了立马感觉高大尚了吧) var day(new Date).getDay()0; //传统if语句 if (day) {alert(Today is Sunday!); }; //运用逻辑…

c语言题目集合

转自:http://blog.csdn.NET/oqqhutu12345678/article/details/69524383 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 2. 写一个“标准”宏M…

arduino 土壤温湿度传感器_嫌arduino太贵?太大?试试ATTINY85!DIY温湿度计入门级教程...

ATTINY85做主控,OLED显示的温湿度计。简介:通过Arduino开发环境,对ATTINY85进行编程,利用DH11温湿度传感器,在SSD1306(128*64)OLED显示屏上显示温度和湿度。材料:ATTINY85DHT11SSD1306 (12864 OLED)电池盒纸…

认识事件冒泡和事件捕获

一.事件冒泡就是多个元素同时响应了同一个事件,前提是这些元素都绑定了这一个事件。这只是我的定义,感觉好理解些。 称它为冒泡,是因为事件会按照DOM元素的层次结构依次执行,就像水泡一样不断浮向顶端。所以称之为事件冒泡。 这个…

BSD配置SSH服务

转载:因为是在vmware上装的FreeBSD,用vmware console把玩系统有点麻烦,就是想起可以开启FreeBSD系统的SSH服务器,再用ssh客户端软件(putty)来更省事一点。以下是配置过程,备忘1.开机启动ssh服务,编辑/etc/r…

计算abc=a!+b!+c!

根据题目,即求abca!b!c! 下面我们设计算法: 设三位数为n,取出每一位数分别放在a、b、c中 通过定义形参,求每位数的阶乘,通过函数返回值返回 主函数中,调用返回值,每一位的阶乘相加与该三位数比较&#xff0…

docker选择安装位置_自定义WSL的安装位置,别再装到C盘啦

本文使用 Zhihu On VSCode 创作并发布为了用docker,今天才决定更新到win10 2004打算另外装一个WSL2的发行版折腾docker和GPU,发现之前装WSL到非系统盘的教程找不到了。现在网上也没找到有这方面的东西,干脆自己写一个留作记录吧~WSL(Windows Subsystem f…

[讨论帖] 程序员如何赚外快?

昨天的一篇文章一个程序员如何快速赚到一百万?引起了大家的热门讨论,现在另开一个贴,讨论一下如何赚钱。 -------------------------- 挣外快需要的是大量的业余时间和强大的意志,如果你是个每天工作十几个小时天天累得像狗一样的…

求两个数的最大公约数和最小公倍数

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 [plain] view plaincopy #include <stdio.h> int main() { int a, b, num1, num2, tmp; printf("Input a & b:"); scanf("%d %d",&num…