Overview

学习JVM首先需要了解一下JVM管理的内存是如何分布的,在看了《深入理解Java虚拟机》和一些博文之后,我准备自己记录一下学习的过程。

下图是JVM中运行时数据区的大致示意图,可以看到主要分为两种内存区域,一种是线程私有的内存区,另一种是所有线程共享的区域。下面会详细描述每个区域存储哪些数据。

程序计数器

我们知道JVM是通过解释Java编译之后的字节码来执行程序的,那么JVM是怎么知道执行到哪一行字节码了呢?答案就是通过程序计数器来指示当前线程执行的字节码行号。我认为应该是JVM模仿CPU中的程序计数器来设计的。

  • 需要注意的是每个线程都有自己私有的一个程序计数器,从而保证互相不干扰。同一时刻一个CPU内核只能执行一个线程上的代码。

  • 当执行Java方法时程序计数器会起作用,但是执行Native方法时计数器值为空。

  • 程序计数器区是JVM内存区中唯一一个不会触发OutOfMemory(OOM)异常的区域。

Java虚拟机栈

Java虚拟机栈也是专属于线程的内存区域,在线程执行每个方法时都会创建一个栈帧(Stack Frame),栈帧中存放了局部变量表、操作数栈、动态链接(reference)等信息。

  • 当线程请起的栈深度大于虚拟机允许的最大深度,就会出发Stackoverflow异常;
  • 如果虚拟机栈允许动态扩展,当无法申请足够内存时会出发OOM异常。

本地方法栈

本地方法栈与Java虚拟机栈的区别就是Java虚拟机栈为Java方法服务,而本地方法栈服务的是Native方法。有些虚拟机会把二者合一,比如HotSpot VM。本地方法栈也会抛出Stackoverflow和OOM异常。

堆是JVM中最大的一块内存区域,主要是用来存放对象实例,几乎所有的对象实例都在堆上分配。

堆也是垃圾收集器(GC)管理的主要工作区域。GC基本采用分代回收算法,所以Java堆可以分为新生代(Young Generation)和老年代(Old Generation),更细一点可以分为Eden、From Survivor空间和To Survivor空间。

Young Generation:主要是用来存放新生的对象,也是GC最经常发生的区域。

Old Generation:主要存放应用程序中生命周期长的内存对象,GC较少发生。

可以通过设置VM参数来扩展堆的大小:

  • -Xms:初试堆大小
  • -Xmx:堆最大大小
  • -XX:NewSize=n :设置年轻代大小
  • -XX:NewRatio=n: 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
  • -XX:SurvivorRatio=n :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

堆也可以抛出OOM异常。

方法区

方法区和堆一样是所有线程共享的内存区域,用于存储虚拟机加载的类信息、metadata、常量、静态变量、JIT编译器编译后的代码等数据,一般称为永生代(Permanent Generation),GC基本不会对永生代进行垃圾收集。

当方法区无法满足内存分配需求时也会抛出OOM异常。

运行时常量池

运行时常量池是方法区中的一部分,用于存放编译期生成的字面量和符号引用。

题外话

直接内存

直接内存不属于JVM管理的内存区域,但是也被频繁使用,其中最典型的例子就是NIO库,在之前一篇文章介绍过。NIO引入了channel和buffer,使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象来作为堆外内存的引用进行操作。这样避免了数据在Java堆和Native堆之间的复制,从而提升性能。

同样,该区域也会抛出OOM异常。

【JVM学习笔记一】JVM内存分布的更多相关文章

  1. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  2. JVM学习笔记:JVM的体系结构与JVM的生命周期

    1 JVM在java平台中的位置 1.1 Java平台组成 Java平台主要由Java虚拟机和Java API这两部分组成.参考Oracle官网. 1.2 java平台结构图 JDK1.2开始,迫于J ...

  3. JVM学习笔记一:内存管理

    参考资料 本文参考:<深入理解Java虚拟机>作者 周志明 知识产权归作者所有 走近java java组成部分:java语言.各平台虚拟机.Class文件结构.java api 类库.第三 ...

  4. java之jvm学习笔记十三(jvm基本结构) 通俗易懂的JVM 文件,没有之一

    http://blog.csdn.net/yfqnihao/article/details/8289363

  5. JVM学习笔记——内存结构篇

    JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...

  6. JVM学习笔记(四)------内存调优【转】

    转自:http://blog.csdn.net/cutesource/article/details/5907418 版权声明:本文为博主原创文章,未经博主允许不得转载. 首先需要注意的是在对JVM内 ...

  7. JVM学习笔记(四)------内存调优

    首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...

  8. jvm内存JVM学习笔记-引用(Reference)机制

    在写这篇文章之前,xxx已经写过了几篇关于改jvm内存主题的文章,想要了解的朋友可以去翻一下之前的文章 如果你还不了解JVM的基本概念和内存划分,请阅读JVM学习笔记-基础知识和JVM学习笔记-内存处 ...

  9. JVM学习笔记-第三章-垃圾收集器与内存分配策略

    JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...

  10. JVM学习笔记——内存模型篇

    JVM学习笔记--内存模型篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存模型部分 我们会分为以下几部分进行介绍: 内存模型 乐观锁与悲观锁 synchronized优化 内 ...

随机推荐

  1. 编写高质量代码改善C#程序的157个建议——导航开篇

    前言 由于最近工作重心的转移,原来和几个同事一起开发的项目也已经上线了,而新项目就是在现有的项目基础上进行优化延伸扩展.打个比方,现在已经上线的项目行政案件的Web管理网站(代码还没那么多相比较即将要 ...

  2. SSH和SFTP简介

    传统FTP 在传输机制和实现原理上是没有考虑安全机制的,因为它们在网络上用明文传送数据.用户帐号和用户口令,别有用心的人非常容易地就可以截获这些数据.用户帐 号和用户口令.而且,这些网络服务程序容易受 ...

  3. //暴力打开某个APP iOS 私有API LSApplicationWorkspace

    //暴力打开某个APP = .= 如果可以打开.直接打开不解释 +(BOOL)isOpenApp:(NSString*)appIdentifierName { Class LSApplicationW ...

  4. Unity3D去掉全屏时的屏幕黑边

    给全屏后不在乎拉伸变形仍想让画面占满屏幕的朋友,网上搜了一上午,实在是没有相关的资料,只能自己琢磨了. 使用Canvas Scaler在全屏后Unity虽然会为我们自动拉伸UI,但拉伸后仍然保持我们在 ...

  5. SMON功能(一):清理临时段

    温故而知新 SMON功能(一) SMON(system monitor process)系统监控后台进程,有时候也被叫做system cleanup process,这么叫的原因是它负责完成很多清理( ...

  6. Md5加密方法

    package com.atguigu.surveypark.util; import java.security.MessageDigest; /** * 数据 */ public class Da ...

  7. 【转】android适配各种分辨率的问题

    http://blog.csdn.net/r8hzgemq/article/details/8243119   Android设备屏幕的尺寸是各式各样的,如小米是4英寸的,Xoom平板是10英寸:分辨 ...

  8. java Joda-Time 对日期、时间操作

    任何企业应用程序都需要处理时间问题.应用程序需要知道当前的时间点和下一个时间点,有时它们还必须计算这两个时间点之间的路径.使用 JDK 完成这项任务将非常痛苦和繁琐.现在来看看 Joda Time,一 ...

  9. 免安装版MySQL安装步骤

    http://downloads.mysql.com/archives/community/ 1:添加环境变量把MySQL解压后的bin目录添加到path环境变量中 2:修改或者添加my-defaul ...

  10. Redmine性能优化方案

    近来公司redmine服务器表现很糟糕,在16核,64GRAM的机器上,压测结果竟然只有每秒5~7个请求,部分页面一个都出不来. 以下是我对Redmine性能优化方案: redmine服务器性能问题排 ...