深入探究JVM(1) - Java的内存区域解析
http://blog.csdn.net/sczyh22/article/details/46652901<br>
Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域。
有的人把JVM管理的内存简单地分为堆内存和栈内存,这样分未免有些太肤浅了。
Java的内存区域主要分为五部分:
程序计数器(PC)
Java 虚拟机栈(JVM Stack)
本地方法栈(Native Method Stack)
Java 堆内存(Java Heap)
方法区(Method Area)
Java内存区域
(图转自网络)
下面我们来解析这几个区域。
1、程序计数器
相信学过计算机组成原理的人都知道,CPU内部的寄存器中就包含一个程序计数器(x86下为eip寄存器,ARM下为R15寄存器),存放程序执行的下一条指令地址。在程序开始执行前,将程序指令序列的起始地址,即程序的第一条指令所在的内存单元地址送入PC,CPU按照PC的地址从内存中读取第一条指令。每一条指令执行时,CPU会自动修改PC的量至下一条指令的地址,指令之间的跳转离不开PC。JVM内存中的程序计数器也是这样的作用,它储存JVM当前执行bytecode的地址。
Java虚拟机允许多个线程同时执行指令。如果有多个线程正在执行指令,那么每个线程都会有一个程序计数器,它是线程私有的。在任意时刻,一个线程只允许执行一个方法的代码。每当执行到一条Java方法的指令时,程序计数器保存当前执行字节码的地址;若执行的为native方法,则PC的值为undefined。
2、Java 虚拟机栈
Java虚拟机栈也是线程私有的,每一条线程都拥有自己私有的Java 虚拟机栈,它与线程同时创建。它描述了Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至完成的过程,都对应一个栈帧从入栈到出栈的过程。关于栈帧详细的内容在后边复习虚拟机字节码执行引擎的时候再说吧。
Java 虚拟机栈在方法调用和返回中也扮演了很重要的角色。因为除了栈帧的入栈和出栈之外,Java虚拟机栈不会再受其它因素的影响,因此栈帧可在系统的堆上分配内存(注意,是系统的Heap而不是Java Heap)。Java虚拟机栈所使用的内存不需要保证是连续的。
3、本地方法栈
本地方法栈和Java虚拟机栈的作用相似,Java虚拟机栈执行的是字节码,而本地方法栈执行的是native方法。本地方法栈使用传统的栈(C Stack)来支持native方法。在HotSpot JVM中Java虚拟机栈和本地方法栈合二为一。
4、Java 堆
在JVM中,Java 堆是可供各线程共享的运行时内存区域,是Java 虚拟机所管理的内存区域中最大的一块。此区域非常重要,几乎所有的对象实例和数组实例都要在Java堆上分配,但随着JIT编译器及逃逸分析技术的发展,也可能会被优化为栈上分配,高大上。。。)。同时,Java 堆也是发生GC收集的主要区域。
从内存回收的角度来看,它可以分为新生代和老年代,再细分可以分为Eden Space,From Survivor Space,To Survivor Space区域。Java堆的容量可以是固定的,也可以随着需要来扩展,并且在用不到的时候自动收缩。
5、方法区
方法区是线程共享的,它储存了每一个类的结构信息,比如运行时常量池(runtime constant pool)、字段和方法数据、构造函数和普通方法的字节码内容,还包括一些初始化的时候用到的特殊方法。方法区是堆的逻辑部分。
在JDK1.7及以前的HotSpot JVM中,方法区位于永久代(Permanent Generation,PermGen)中。由于永久代内可能会发生内存泄露或溢出等问题而导致的java.lang.OutOfMemoryError: PermGen ,JEP小组从JDK1.7开始就筹划移除永久代(JEP 122: Remove the Permanent Generation),并且在JDK 1.7中把字符串常量,符号引用等移出了永久代。到了Java 8,永久代被彻底地移出了JVM,取而代之的是元空间(Metaspace):
In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.
所以从Java 8开始,方法区被移至Metaspace 内。有关Metaspace的相关总结,见下一篇文章。
6、运行时常量池
运行时常量池是class文件中每一个类或接口的常量池表的运行时表示形式,是方法区的一部分。它包括了若干种不同的常量。常量池表存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。运行时常量池具有动态性,运行期间也可以将新的量放到运行时常量池中,典型的应用是String类的intern方法:
public native String intern()
1
JDK 7开始,字符串常量和符号引用等就被移出永久代:
符号引用迁移至系统堆内存(Native Heap)
字符串字面量迁移至Java堆(Java Heap)
下一篇文章我将会总结Java 8中的Metaspace相关知识。
深入探究JVM(1) - Java的内存区域解析的更多相关文章
- 重读《深入理解Java虚拟机》一、Java虚拟机内存区域的划分
一.Java虚拟机内存区域如何划分 1.Java虚拟机内存区域的划分 区域名称 作用(用途) 类型 特点 虚拟机规定异常情况 内存分配与回收 其他说明 1 程序计数器 指示当前正在执行的字节码指令地址 ...
- java的内存区域
java的内存区域分为程序计数器.java虚拟机栈.本地方法栈.java堆.方法区.运行时常量池. 1.程序计数器 2.java虚拟机栈 3.本地方法栈 4.java堆(新生代和老年代) 5.方法区( ...
- JVM学习第一天(虚拟机的前世今生与与Java的内存区域)
其实说JVM的时候有很多人会懵, 也很不理解,我会写Java代码就可以了,我干嘛要学这个,其实不是的,学习JVM是很有必要性的; 为什么要了解JVM 1:写出更好,更健壮的Java程序; 2:提高Ja ...
- java虚拟机内存区域的划分以及作用详解
序言 为什么有时候学着学着会突然之间觉得一切度是那么无趣,男的每个月也有那么几天难道?哈哈,不然是什么,我还是要坚持,可以做少一点,但是不能什么度不做.总会过去的,加油 --WH 一.运行时数据区 什 ...
- 【转】Java之 内存区域和GC机制
转自:Leo Chin 目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage ...
- Java虚拟机内存区域堆(heap)的管理
在上一节中Java 出现内存溢出的定位以及解决方案 中对于Java虚拟机栈以及方法区的内存出现的异常以及处理方式进行了解析,由于Java虚拟机对于堆的管理十分复杂,并且Java虚拟机中最基本的内存区域 ...
- 总结Java虚拟机内存区域模型
本篇文章主要来总结一下Java虚拟机内存的各个区域,以及这些区域的作用.服务对象以及其中可能产生的问题,作为大家的面试宝典. 首先我们来看一下Java运行时的数据区域,Java虚拟机在执行Java程序 ...
- 一、java虚拟机内存区域
内存区域 java虚拟机在java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.java虚拟机规范将JVM管理的内存分为:程序计数器.本地方法栈.Java虚拟机栈.方法区.Java堆.如下 ...
- JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)
1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...
随机推荐
- webpack初体验之模块化开发
写在前面的话 上次写过一篇关于webpack入门的博客,当时只是说借助node来完成开发,并用webpack打包以让浏览器识别.其实其主要思想就是实现前端模块化开发. 众所周知,历史上,JavaScr ...
- C++类中的函数重载
1,本课程最初阶段就学习了函数重载,但是那时研究目标仅限于全局函数,到目前 为止我们学习了三种函数: 1,全局函数: 2,普通成员函数: 3,静态成员函数: 这三种不同类型的函数之间是否可以构成重载, ...
- oracle系统视图SQL语句整理
-- DBA/ALL/USER/V_$/GV_$/SESSION/INDEX开头的绝大部分都是视图 -- DBA_TABLES意为DBA拥有的或可以访问的所有的关系表. -- ALL_TABLES意为 ...
- D - Disjoint Set of Common Divisors
https://atcoder.jp/contests/abc142/tasks/abc142_d 题意 求满足互素条件下的A和B的因子最多有几个 思路: 分解gcd(A,B)的质因子,再加上1: # ...
- [LeetCode] 132. 分割回文串 II
题目链接 : https://leetcode-cn.com/problems/palindrome-partitioning-ii/ 题目描述: 给定一个字符串 s,将 s 分割成一些子串,使每个子 ...
- 解决intellij idea控制台中文乱码
乱码原因: 1.系统语言:英文 英文系统下遇到乱码问题,分析了程序执行参数如下: ps -ef | grep java 执行后得到如下的结果,省略了classpath: /System/Library ...
- thinkphp5 验证码出不来的常见问题
对于thinkphp如何实现验证码,我这里就不介绍了.直接看之前的文章 http://www.cnblogs.com/qqblog/p/6639419.html.下面,我能想出来的是,我自己在开发过程 ...
- Maven下载清除jar包
maven jar包下载命令行方式 在STS中下载JAR包时经常卡住无法继续下载,这时可以用命令行方式进行下载.在终端中今入到该项目的根目录下,然后mvn clean;mvn install;等待下载 ...
- VB中RaiseEvent语句的功能及用法
Creat a new class named Class1, it's codes like this: Public Event MyEvent() Public Sub RaiseTheEven ...
- Python3找出List中最大_最小的N个数及索引
# -*- coding: utf-8 -*- import heapq nums = [1, 8, 2, 23, 7, -4, 18, 23, 24, 37, 2] # 最大的3个数的索引 max_ ...