这篇文章可以说是摘抄自周志明的《深入理解Java虚拟机》,但是加上了自己的理解,印象可以更深些。

Java虚拟机在执行Java程序的时候会把他所管理的内存划分为若干个不同的数据区域,各个区域有各自的用途,以及创建和销毁的时间。有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户线程的启动和结束而创建和销毁。

Java虚拟机会把运行时的数据区域分为以下几个区域:

程序计数器:

程序计数器是一块很小的内存空间,代表着当前线程执行的字节码的行号指示器,记录着所执行的行号,java虚拟机执行的是由后缀名为.java的文件编译而来的.class文件(字节码文件),所以字节码解释器根据程序计数器来执行字节码文件。每个线程都有自己的程序解释器,这样才能保证程序的正确执行,也就是说程序计数器是线程私有的。

Java虚拟机栈:

java虚拟机栈是用来描述java方法的内存模型,每个方法在执行的同时都会创建一个栈帧,而这个栈帧存储的是方法中的局部变量,操作的数据,方法的入口返回值等信息,当一个方法被调用的时候,就代表着栈帧的入栈直至方法的结束代表着栈帧的出栈。因为虚拟机栈存储的数据决定了他也是线程私有的,每个线程都拥有一个虚拟机栈记录着方法的内容。我们平时所说的栈就是指的是虚拟机栈,其中存储着基本数据类型和指向堆内存中对象的指针(对象的引用)。

本地方法栈:

这块区域和虚拟机栈执行的操作其实是一致的,但是他们之间的服务对象不一样,虚拟机栈为java方法服务,而本地方法栈为native方法服务,我们在看源码的时候经常了一看到用native关键字修饰的方法,这种方法的实现是用c/c++实现的,我们在平时是看不到他的源码实现的。

Java堆:

堆内存是这几块内存区域中最大的一块,堆内存存在的目的是存放对象的实例(通过new创建的对象,对象的引用放在虚拟机栈中指向堆中的实例),在虚拟机启动的时候堆内存也就被创建了,这块内存被所有线程共享,在虚拟机运行期间的所有线程创建的对象的实例都被存储在堆内存中。既然堆被线程所共享,那么线程创建的对象不能一直存放在这里,总会有装不下的时候,在一定条件下,java虚拟机会触发垃圾回收机制(GC),来回收这里被看作没有用的对象,虚拟机所管理的垃圾回收器总是会对这块区域进行管理操作。关于垃圾回收(GC)机制可以看另一篇文章:Java
GC垃圾回收机制

方法区:

方法区和堆内存一样,是各个线程共享的数据区域,看到这个方法区这个名字很快能想到这个区域存方法信息,事实上方法区存放的数据很多,包括被虚拟机加载的类信息,用final修饰的常量,String对象,用static修饰的静态变量。

运行时常量池:

准确的说这块区域属于方法区,也就受到了方法区的空间限制,之前所说的String对象,就是字符串常量就是存放在这里,编译期生成各种字面值和符号引用,将在类价在后放入方法区的运行时常量池的。运行时常量池的存储具有动态性,并不是在类加载时才能放入数据,在程序运行期间也可以有新的常量放入。String类中的intern()方法就是这种特点,详看之前转载的一篇文章:String的intern()方法详解

直接内存:

这块区域和java中的新的io方式(NIO)有关,不属于虚拟机的运行时数据区。NIO是一种基于通道,缓冲区的io方式。后面会详细看看。

参考:《深入理解Java虚拟机 JVM高级特性与最佳实践》周志明

Java运行时内存划分的更多相关文章

  1. Java运行时内存划分与垃圾回收--以及类加载机制基础

    ----JVM运行时内存划分----不同的区域存储的内容不同,职责因为不同1.方法区:被线程共享,存储被JVM加载的类的信息,常量,静态变量等2.运行时常量池:属于方法区的一部分,存放编译时期产生的字 ...

  2. JVM发展史和Java运行时内存区域

    目前三大主流JVM: Sun HotSpot:Sun于1997年收购Longview Technologies公司所得.Sun于2009年被Oracle收购. BEA JRockit:BEA于2002 ...

  3. 理解JVM之JAVA运行时内存区域

    java运行时内存区域划分为方法区,堆区,虚拟机栈区,本地方法栈,程序计数器.其中方法区跟堆区是线程共享的数据区,其他的是线程私有的数据区. 1.程序计数器 程序计数器(PC)是一块较小的内存,他是存 ...

  4. java运行时内存模式学习

    学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...

  5. Java程序运行时内存划分

    1.Java程序跨平台运行的原因 主要原因是:各种平台的JVM和字节码文件 Java源程序--具体平台的机器代码文件---被编译器翻译成平台无关的Class文件,又用特定JVM运行字节码文件,JVM在 ...

  6. Java运行时内存

    对于java程序员来说,并不必显示地对内存进行管理,一切都交给java虚拟机去做吧,而且,你也不一定做得比java虚拟机来得专业.好像所有内存管理都交给虚拟机去做就万事大吉了,但是,事实有时并非如此, ...

  7. JAVA虚拟机运行时内存划分--运行时数据区域

    Java虚拟机在执行java程序时会把内存划分为以下几个不同的数据区域: java虚拟机内存划分(运行时)1.线程私有的: 程序计数器(Program Counter Register):可以看作当前 ...

  8. java运行时内存分配详解

    一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Java进程对应唯一一个JVM实例,每一个JVM实例唯一对应一个堆,每一个线程有一个自己私 ...

  9. 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型

    一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...

随机推荐

  1. 注意Vietnamese_CI_AS排序规则下的特殊字符大小敏感问题

    注意Vietnamese_CI_AS排序规则下的特殊字符大小敏感问题   最近,在SQL Server中遇到了Vietnamese_CI_AS排序规则的特殊字符的大小写敏感问题,是的,你没有看错,这句 ...

  2. Java之indexOf()方法

    Java之indexOf()方法 1.方法介绍 (1)indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引 (2)indexOf(String str) 返回指定子字符串在此字符 ...

  3. JSP中的include有哪些?有什么区别?

    JSP中的include有哪些?有什么区别? 1.JSP中的include有哪些 (1)<%@include file="" %> (2)<jsp:include ...

  4. Spring Boot 文件上传

    其实网上已经有很多这样的文章了.为什么我还要记录一下呢?原因是在工作中对接外系统时,碰到了他们调取我们文件上传接口确存在着http请求头部规范的情况,从而导致用传统方法获取不到参数.今天就来整理下Sp ...

  5. 自定义JS乘法运算误差解决!

    在实际开发中遇到这样一个乘法公式:数量*单价=总价 像这样的浮点数列子:200*8.2,JS算出的结果是: 像这种浮点数的乘法计算就会有误差,我们需要得到准确的值应该是:1640,与我们后台C#计算结 ...

  6. 当发现你的OpenStack虚拟机网络有问题,不妨先试一下这16个步骤

    1. Security Group全部打开,这是最基本的,但是很多人容易忘记 其实遇到过无数这种场景了,Debug了半天网络问题,各种手段都用上了,最后发现安全组竟然没有打开. 2. 通过界面查看虚拟 ...

  7. jquery的各种插件调用(有些已经过时,以备注,其他的一些可以闲的时候用作拆解)

    jquery的valiteDate验证插件应用 <!DOCTYPE html> <html>        < head>            < meta ...

  8. Poj2749:Building roads

    题意 有 N 个牛栏,现在通过一条通道(s1,s2)要么连到s1,要么连到s2,把他们连起来,他们之间有一些约束关系,一些牛栏不能连在同一个点,一些牛栏必须连在同一个点,现在问有没有可能把他们都连好, ...

  9. [BZOJ2654] tree (kruskal & 二分答案)

    Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V,E,need分别表示点数,边数和需要的白色 ...

  10. Redis之Zset

    一.Redis之Zset简介 1. 有序集合Zset是String类型的有序集合. 2. Zset中每个元素都会关联一个double类型的分数值,redis通过分数值来为集合中所有成员进行从小到大排序 ...