[Java]Java内存模型

雾桩装饰
• 阅读 942

[Java]Java内存模型

本地库接口是操作系统实现的,对应的栈就是本地方法栈

方法区
  • 方法区被所有线程共享
  • 存储已被虚拟机加载的类信息常量(final)、静态变量(static)、(构造方法、接口信息)等数据
  • 垃圾收集行为在这个区域比较少出现,回收目标主要是针对常量池的回收和对类型的卸载
  • 运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载后存放到运行时常量池。
PC Register 程序计数器

每个线程都有一个程序计数器,就是一个指针,指向方法区中的方法字节码(下一个要执行的指令代码)

本地方法栈

Native方法的栈

八字箴言:栈管运行,堆管存储

虚拟机栈

当一个方法被调用时就产生了一个栈帧,并被压入到栈中

  • 线程私有
  • 生命周期和线程相同
  • 基本类型变量(boolean,byte,char,int....)和对象的引用变量(引用指针或句柄) 在栈内存中分配(简单理解就是在方法里定义的各种局部变量,自定义类的变量只有指针)
  • 栈中存储的是栈帧(对应一个方法), 栈帧保存了 :
    1). 本地变量(输入/输出参数,方法内定义的局部变量)
    2). 栈操作(记录出栈、入栈的操作)(以及动态链接、方法出口)
  • 局部变量所需要的内存在编译期间完成分配
堆内存

堆内存示意图
[Java]Java内存模型

实例化对象的产生到消亡发生在新生区
新生区又分为两部分:

  1. Eden Space, 所有的新生对象在这里产生
  2. Survivor 0 , Survior 1;
  • 当Eden Space 用完的时候,程序又需要创建新对象,JVM 垃圾回收器将对Eden Space 进行Minor GC:将不再被其他对象引用的对象销毁,然后将Eden中剩余的对象移动到 Survior 0中。
  • 如果Survior 0 也满了, 再对该区进行垃圾回收,然后移动到Survior 1区
  • 同样的,如果Survior 1 区也满了,将会把剩余的对象移到老年代。如果老年代也满了,则会发生Major GC (Full GC),对老年代的内存进行清理。如果老年代经过GC后仍无法保存对象,就会产生OOM。
注:
如果出现 OOM :Java heap space的错误,说明JVM的堆内存不够,原因有两点:
(1).堆内存设置的不够大,默认最大是机器内存的1/4,可以通过参数-Xms(初始内存), -Xmx(最大内存)
(2). 代码中创建了大量的大对象,并长时间不能被垃圾收集器收集

可以new出一个很大的对象,这个对象大小需要小于机器最大内存,并调整JVM参数

老年代

用于保存从新生代筛选出的Java对象,一般池对象(如jdbc连接池)都在这个区域活跃,很少发生GC

永久代
  • 没有垃圾回收,关闭JVM才会释放所占用的内存
  • 常驻内存
  • 用于存放JDK自身所携带的Class,Interface的元数据(或者说是存储的是运行环境所必须的类信息)
如果出现 OOM:PermGen space
说明JVM对永久代设置的内存不够。一般出现这种情况,都是程序启动需要加载大量的第三方Jar包。

JAVA7永久代 === JAVA8 元空间

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
java运行时数据区
运行时数据区包括以下几个部分:程序计数器,堆,java栈,本地方法栈,方法区1.程序计数器:当CPU需要执行指令时,需要从程序计数器中获取当前需要执行的指令所在存储单元的地址。用来指示执行哪条指令。其大小不会随程序的执行而发生改变。2.Java栈:java方法执行的内存模型。存放的时一个个栈帧,每个栈帧对应一个被调用的方法。  栈帧中包括:局
Wesley13 Wesley13
4年前
java之jvm
1.JVM内存模型_线程独占:栈,本地方法栈,程序计数器线程共享:堆,方法区_回答以上问题是需回答两个要点:1\.各部分功能2\.是否是线程共享2.JMM与内存可见性JMM是定义程序中变量的访问规则,线程对于变量的操作只能在自己的工作内存中进行,而不能直接对主内存操作.由于指令重排序,读写的顺序会被打乱,因此JMM需要
Wesley13 Wesley13
4年前
java的对象模型
java中的对象在内存中,究竟是怎样一种存在?这篇随笔,我们就来一探究竟。可能不够深入,但是我们把理解到位,深入到我们需要的程度这样即可。先来看下jvm的内存模型:程序计数器虚拟机栈和本地方法栈堆方法区(运行时常量池)!(https://oscimg.oschina.net/oscnet/3528c94568da5147907
灯灯灯灯 灯灯灯灯
4年前
一次性带你了解清楚Java内存模型!
Java内存模型咳咳咳,能看完的都是人上人。。。。Java虚拟机内部使用JMM(Java内存模型)将内存划分为两个逻辑单元,线程栈(或者叫本地内存)和堆。每一个线程都有属于自己的线程栈,在线程栈中会保存局部变量(也叫做本地变量)、方法中定义的参数和异常处理器的参数(catch中的参数);这些参数和变量都属于线程局部操作,会被隔离,所以不受内存模
红橙Darren 红橙Darren
4年前
C进阶 - 内存四驱模型
一.内存四驱模型不知我们是否有读过《深入理解java虚拟机》这本书,强烈推荐读一下。在java中我们将运行时数据,分为五个区域分别是:程序计数器,java虚拟机栈,本地方法栈,java堆,方法区。在c/c中我们将运行时数据,分为四个区域分别是:栈区,堆区,数据区,代码区。我们详细来介绍下:1.栈区:由编译器自动分配释放,存放函数的
Stella981 Stella981
4年前
JVM内存模型和类加载机制
JVM内存模型Java代码是运行在Java虚拟机(JVM)上的,Java虚拟机通过解释执行(解释器)或编译执行(编译器)来完成。Java内存模型分为5个部分:方法区(MethodArea),Java堆(Heap),Java栈(VMStack),本地方法栈(NativeMethodStack),程序计数器(PC寄存器)!(ht
Stella981 Stella981
4年前
JVM内存区域划分
JVM内存区域划分一、JVM运行时数据区划分根据《Java虚拟机规范》JVM会把它管理的内存划分为若干个不同的数据区域,如下图所示:方法区、堆、栈(虚拟机栈、本地方法栈)、程序计数器。线程私有的意思是指,JVM每遇到一个新的线程就会为他们分配栈和程序计数器。!(https
Wesley13 Wesley13
4年前
JAVA中的栈和堆【转】
 原文链接 https://www.cnblogs.com/ibelieve618/p/6380328.htmlJAVA在程序运行时,在内存中划分5片空间进行数据的存储。分别是:1:寄存器。2:本地方法区。3:方法区。4:栈。5:堆。基本,栈stack和堆heap这两个概念很重要,不了解清楚,后面就不用学了。以下是这几天栈和堆的学习记录和心得。得
Stella981 Stella981
4年前
GC roots
<divid"cnblogs\_post\_body"class"blogpostbody"<p1.虚拟机栈(本地变量表)引用的对象</p<div2.方法区静态属性引用的对象</div<div3.方法区常量引用的对象</div<div4.本地方法栈JNI(一般指naive方法)中引用的对象</div<div&nbsp;<
Wesley13 Wesley13
4年前
Java堆,方法区,Java栈和本地方法栈浅析
最近在看《深入理解Java虚拟机》,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构:!(http://static.oschina.net/uploads/img/201611/04115646_t6Rm.gif)感觉有必要通过几个实在的例子来加深对这
Stella981 Stella981
4年前
JVM总结3
    垃圾收集GarbageCollection通常被称为“GC”,它诞生于1960年MIT的Lisp语言,经过半个多世纪,目前已经十分成熟了。    jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于java堆和
雾桩装饰
雾桩装饰
Lv1
在奋斗中释放青春激情,在奉献中追逐青春理想。
文章
2
粉丝
0
获赞
0