jvm内存模型

jvm内存模型可以分为 堆、方法区、虚拟机栈、本地方法栈、程序计数器五个区域。见下图。

1.方法区

方法区是各个线程共享的内存区域,用于存储类的信息、常量与静态变量。

HotSpot VM把方法区也称为永久代,Permanent Space。永久代对垃圾回收没有显著影响。

1.1 vm参数

-XX:PermSize //永久代最小空间

-XX:MaxPermSize //永久代最大空间

示例: -XX:PermSize=100m -XX:MaxPermSize

1.2相关报错

java.lang.OutOfMemoryError:Perm space

永久代内存溢出,调大内存即可。

2.堆

堆通常是jvm内存中最大的一块,用于盛放对象。

堆又可以分为新生代与老年代,见图2-1.

图2-1 jvm堆与方法区的内存模型

permanent space为永久代空间;heap space为堆空间,它又分为新生代空间与老年代空间。

2.1新生代空间

它又可以分为2部分——Eden space与Survivor Spaces,后者包括s0与s1。

2.1.1 Eden space

Eden ['i:dən]
n. 伊甸园(《圣经》中亚当和夏娃最初居住的地方)

新创建的对象将放入Eden Space。

2.1.2 survivor space

又可以分为 s0  (survivor 0) 与 s1(survivor 1)。

当Eden区满时,触发一次minor GC。还存活的对象将被复制到s0,同时清空Eden区域。

当Eden区再次满时,触发一次minor GC。Eden+s0(不管s0有没有满)还存活的对象将被复制到s1,同时清空Eden+s0区域。

当Eden区再次满时,触发一次minor GC。Eden+s1(不管s1有没有满)还存活的对象将被复制到s0,同时清空Eden+s1区域。

如此往复。。。

注意survivor from 与survivor to的概念和s0与s1的概念。

2.1.3 复制算法

新生代采用的就是复制算法。当survivor from 内存用完,就将还活着的对象复制到另外一块survivor to上面。复制算法不会产生内存碎片。

新生代GC也是需要stop the world的,通常为几十毫秒。

2.2 老年代空间

在新生代中经历了N次垃圾回收后仍然存活的对象,就会被放到老年代中。因此可以认为老年代中存放的都是一些生命周期较长的对象。

2.3 年龄

一个对象,每经历一次GC(minor GC 或 major GC),年龄就加一岁。
-XX:MaxTenuringThreshold=15
指定对象到达15岁时被移到Old区。默认值为15。

需要注意的是,并不是年龄非得到达指定值后才会被移到老年代,JVM还有自己的一套规则,烦人。
-XX:+PrintTenuringDistribution
这个参数用于显示每次Minor GC时Survivor区中各个年龄段的对象的大小。

2.4 vm参数

-Xmx
//最大堆内存

-Xms
//最小堆内存

-Xmn
//新生代内存

示例:-Xms2048m -Xmx5120m

-XX:SurvivorRatio//新生代中,Eden区域与survivor区域的比值。默认为8。

2.5 常见错误

java.lang.OutOfMemoryError:java heap space

堆溢出。

3. 程序计数器

名为PC,Program Counter,是一个寄存器,存放该线程要执行的下一条语句的位置。

每个线程都有自己的PC,线程间不共享。

4.java虚拟机栈

每个线程都有自己的java虚拟机栈,线程间不共享。

每当进入一个函数时,创建栈帧(即Stack Frame,内含局部变量与函数出口等信息),入栈,函数执行完退出时,出栈。

4.1vm参数

-Xss 
//每个线程的栈大小,默认为1M

示例: -Xss 2m

4.2 常见报错

java.lang.StackOverflowError

栈溢出。默认情况下函数嵌套达到2000层是没有问题的。可以认为调大栈空间。

5.本地方法栈

每个线程都有自己的本地方法栈,线程间不共享。

与java虚拟机栈类似,服务于本地(native)代码。

时间: 2024-10-24 17:25:44

jvm内存模型的相关文章

JVM内存模型及垃圾回收算法

原文地址: http://blog.csdn.net/kingofworld/article/details/17718587   JVM内存模型总体架构图 程序计数器多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源.因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令.线程私有的内存区域.如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空.虚拟机栈线程私有的,与线程在同一时间创建.

JVM深入学习笔记三:JVM 内存模型

1. JVM运行时内存 图 程序计数器 当前线程执行的字节码的行号指示器,线程通过这部分来选择下一条指令,通过这个部分来实现分支,循环等操作.没有OOM,没有参数可以控制 Java虚拟机栈 描述方法执行的内存区,一个方法的执行就是形成一个栈帧入栈和出栈的过程 栈帧(局部变量表,操作数栈, 动态链接),  局部变量表就是参数和一些方法内的局部变量,操作数栈是方法中的一些操作的运算用的字节码, 动态链接是区别于静态链接的部分,主要包含一些执行信息和资源 包含了两种异常: 线程请求的栈深度大于虚拟机所

Java笔记:Java内存模型

1. 基本概念 <深入理解Java内存模型>详细讲解了java的内存模型,这里对其中的一些基本概念做个简单的笔记.以下内容摘自 <深入理解Java内存模型>读书总结 并发 定义:即,并发(同时)发生.在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行. 并发需要处理两个关键问题:线程之间如何通信及线程之间如何同步. 通信:是指线程之间如何交换信息.在命令式编程中,线程之间的通信机制

浅谈java内存模型

不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结java的内存模型,要解决两个主要的问题:可见性和有序性. 我们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的.JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于java开发人员,要清楚在jvm内存模型的基础上,如果解决多线程的可见性和有序性. 那么,何谓可见性? 多个线程之

《深入解析Android 虚拟机》——2.6 Java内存模型

2.6 Java内存模型 不同的平台,内存模型是不一样的,但是JVM的内存模型规范是统一的.其实Java的多线程并发问题最终都会反映在Java内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结Java的内存模型,要解决两个主要的问题:可见性和有序性. 人们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的.JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于Java开发人员,要清楚在JVM内存模型的基础上,如果解决多线程的可见性和有序性. 那么,

《深入解析Android 虚拟机》——第2章,第2.6节Java内存模型

2.6 Java内存模型不同的平台,内存模型是不一样的,但是JVM的内存模型规范是统一的.其实Java的多线程并发问题最终都会反映在Java内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结Java的内存模型,要解决两个主要的问题:可见性和有序性. 人们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的.JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于Java开发人员,要清楚在JVM内存模型的基础上,如果解决多线程的可见性和有序性. 那么,何

JVM学习(3)——总结Java内存模型

俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简介 volatitle关键字 原子性 可见性 有序性 指令重排 先行发生--happen-before原则 解释执行和编译执行 其他语言(c和c++)也有内存模型么?   为什么需要关注Java内存模型?   之前有一个我实习的同事(已经工作的)反讽我:学(关注)这个有什么用? 我没有回答,我牢记一

JVM学习笔记(一)——内存模型

对于Java程序员来说,他们相比C++程序员最幸福的一点就是不用自己管理内存,内存的分配和回收都由虚拟机完成.然而,正是由于该原因,一旦虚拟机内存管理出现问题,比如出现内存泄漏或溢出,排查起来将是非常困难的.所以尽管不用亲自动手管理内存,但是了解虚拟机的内存管理机制还是很有必要的. 运行时数据区域 首先来看下Java虚拟机在运行时的数据区域划分,Java虚拟机在Java程序运行时会将内存区域划分成若干个不同的区域,各自负责不同的职责. 1.1 程序计数器 程序计数器(PC)的概念比较简单,记录当

Java线程/内存模型的缺陷和增强

Java在语言层次上实现了对线程的支持.它提供了Thread/Runnable/ThreadGroup等一系列封装的类和接口,让程序员可以高效的开发Java多线程应用.为了实现同步,Java提供了synchronize关键字以及object的wait()/notify()机制,可是在简单易用的背后,应藏着更为复杂的玄机,很多问题就是由此而起. 一.Java内存模型 在了解Java的同步秘密之前,先来看看JMM(Java Memory Model). Java被设计为跨平台的语言,在内存管理上,显