java虚拟机内存可以分为独占区和共享区。

独占区:虚拟内存栈、本地方法栈、程序计数器。

共享区:方法区、Java堆(用来存放对象实例)。

  程序计数器

  比较小的内存空间,当前线程所执行的字节码的行号指示器,如果执行的为java方法,那么计数器记录的是正在执行的虚拟机字节码指令的地址,如果方法是native方法,则为undefined。

  字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器完成。

  在任何一个确定的时刻,一个处理器只能执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各个线程之间的程序计数器互相不影响,独立存储。  

  Java虚拟机栈

  生命周期和线程相同。存放方法时运行的数据,描述的是Java方法执行的动态内存模型。

  栈帧:每次方法执行,就会创建一个栈帧,栈帧进栈就开始执行。如果调用其他方法,则又会创建一个栈帧,就按照栈的先进先出来进行。栈帧用来存储局部变量表、操作数栈、方法出口等。

  局部变量表:存放编译器可知的基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用等,大小不会改变。只有double和long会占用两个局部变量空间,其他只占用一个。局部变量表的大小在编译期间被确定。

  本地方法栈

  本地方法栈的作用和虚拟机栈作用相似,只不过虚拟机栈为Java方法(也就是字节码)服务,本地方法栈为Native方法服务。

  Java堆

  在大多数情况上来说,Java堆是Java虚拟机锁管理的内存中最大的一块。Java堆是被所有进程共享的一块内存区域。Java堆的目的就是存放对象实例,几乎所有的对象实例都要在这分配内存。

  Java堆在虚拟机启动时创建。

  Java堆是垃圾收集器管理的主要区域,所以又称GC堆。Java堆又可以分出来新生代和老年代,再细致一点可以分出来Eden、From Survivor、To Survivor空间。进一步的划分只要是为了更好地利用回收内存。

  Java堆可以处于物理上不连续的区域,只要它们逻辑上是连续的。

  方法区

  方法区用来存放已经被虚拟机加载的类信息、常量、静态变量等。

  在某些虚拟机上(HotSpot),方法区又称为永久代,这样垃圾收集器也可以管理方法区。

  运行时常量池

  运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用来存放编译期生成的各种字面量和符号引用,这部分在类加载后进入方法区的运行时常量池进行存放。

  运行期间也可以将新的常量存放在池中,如String类中的intern方法。

  Hotspot虚拟机在Java堆中全过程

  对象的创建

  虚拟机遇到一条new指令,首先去检查这条指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用是否被加载、解析、初始化过。如果没有,那么必须先执行累的加载过程。

  在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象内存的大小在类加载完成之后便可以确定,为对象分配内存的任务等同于把一块确定大小的内存从Java堆中划分出来(指针碰撞和空闲列表,选择哪种方式由Java堆是否规整决定的)。

  内存分配完之后,虚拟机将分配的内存空间都初始化为零值(不包括对象头)。接下来,虚拟机将要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头之中。

  在以上的工作完成之后,从虚拟机的角度上看,一个新的对象已经诞生了,但是从Java程序的角度看,对象创建才刚刚开始(init方法还没执行,所有字段都还为零),所以一般来说执行new指令之后再执行init方法,这样一个真正可用的对象才算产生出来。

  对象的内存布局

  在Hotspot虚拟机中,对象在内存的存储的布局分为3块:对象头、实例数据、对齐补充。

  对象头中包括两部分,第一部分用于存储对象自身的运行时数据,比如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID,官方称之为Mark Word。考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间中存储更多的信息。

  对象头的另外一部分是类型指针,就是对象指向它的类元数据的指针,从而虚拟机可以通过这个确定该对象是哪个类的实例。如果对象是一个数组,那么对象头中还有一段记录数组长度的数据。

  实例数据是对象真正存储的有效信息,也是代码中所定义的各种类型的字段内容。

  对其补充的作用就是JVM要求对象内存的起始地址必须是8字节的整数倍,所以用来补充保证满足这一个要求。

  对象的访问定位

Java虚拟机-内存tips的更多相关文章

  1. java虚拟机内存不足,“Could not create the Java Virtual Machine”问题解决方案

    java虚拟机内存不足,"Could not create the Java Virtual Machine"问题解决方案 在运行java程序时,遇到问题"Could n ...

  2. Java虚拟机内存模型及垃圾回收监控调优

    Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...

  3. 如何设置Java虚拟机内存以适应大程序的装载

    Java虚拟机对于运行时的程序所占内存是有限制的,当我们的项目或者程序很大时,往往会照成内存溢出. 举个例子: public class SmallTest1 { public static void ...

  4. 打包apk java 虚拟机内存不足

    解决方案:在android->sdk->build-tools-android-version 中有个 dx.bat dx.bat --dex 命令的dx.bat脚本有这样一句代码 REM ...

  5. Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)

    Java虚拟机内存溢出异常--<深入理解Java虚拟机>学习笔记及个人理解(三) 书上P39 1. 堆内存溢出 不断地创建对象, 而且保证创建的这些对象不会被回收即可(让GC Root可达 ...

  6. JVM基础系列第6讲:Java 虚拟机内存结构

    看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,J ...

  7. 总结Java虚拟机内存区域模型

    本篇文章主要来总结一下Java虚拟机内存的各个区域,以及这些区域的作用.服务对象以及其中可能产生的问题,作为大家的面试宝典. 首先我们来看一下Java运行时的数据区域,Java虚拟机在执行Java程序 ...

  8. Java虚拟机内存分配详解

    简介 了解Java虚拟机内存分布的好处 1.了解Java内存管理的细节,有助于程序员编写出性能更好的程序.比如,在新的线程创建时,JVM会为每个线程创建一个专属的栈 (stack),其栈是先进后出的数 ...

  9. 重读《深入理解Java虚拟机》一、Java虚拟机内存区域的划分

    一.Java虚拟机内存区域如何划分 1.Java虚拟机内存区域的划分 区域名称 作用(用途) 类型 特点 虚拟机规定异常情况 内存分配与回收 其他说明 1 程序计数器 指示当前正在执行的字节码指令地址 ...

随机推荐

  1. 学习tornado:异步

    why asynchronous tornado是一个异步web framework,说是异步,是因为tornado server与client的网络交互是异步的,底层基于io event loop. ...

  2. 漫谈程序员(十二)IT程序猿之猿体是革命的本钱

    IT程序猿之猿体是革命的本钱 前言 程序猿的一大特点就是加班.加班.不停地加班.... 为了美好的生活,为了生活的更加美好.我们选择勤勤恳恳,踏踏实实. 但是,工作只是生活的一部分.生命中最重要的莫过 ...

  3. Java最最常用的100个类排序(非官方)

    下面这句话是引用"大部分的 Java 软件开发都会使用到各种不同的库.近日我们从一万个开源的 Java 项目中进行分析,从中提取出最常用的 Java 类,这些类有来自于 Java 的标准库, ...

  4. Java图形界面编程生成exe文件

    1. 先将代码打成jar,然后使用exe4j转成exe ext4j下载 链接:http://pan.baidu.com/s/1kTCIZtX 密码:pvj1 打开EXE4J Advanced Opti ...

  5. 开源数字媒体资产管理系统:Razuna安装方法

    Razuna以一个使用Java语言编写的开源的数字媒体资产管理(Digital Asset Management)系统.在这里翻译一下它的安装步骤. Razuna包含以下版本: Razuna Stan ...

  6. java缓存系统

    第一版 package cache; import java.util.HashMap; import java.util.Map; public class Cache1 { private Map ...

  7. U盘无法安装win10提示Your PC/Device needs to be repaired

    前一阵子把笔记本自带的win8升级到8.1,又升级到win10. 差不多有一个月没有开机,前几天开机后进不了系统,出现如下图的提示.买电脑自带的win8是正版的,但升级到win10后就过期了,也真是坑 ...

  8. UML之协作图

    面向对象动态建模,用于建立行为的实体间行为交互的四种图,状态图(Stage Diagram),时序图(Sequence Diagram),活动图(Activity Diagram)前面的博客中,我们已 ...

  9. 解决winform窗体闪烁问题

    如果你在Form中绘图的话,不论是不是采用的双缓存,都会看到图片在更新的时候都会不断地闪烁,解决方法就是在这个窗体的构造函数中增加以下三行代码: 请在构造函数里面底下加上如下几行: SetStyle( ...

  10. Android ROM开发(一)——Windows下Cygwin和Android_Kitchen厨房的安装

    Android ROM开发(一)--Windows下Cygwin和Android_Kitchen厨房的安装 很久没有碰到ROM开发了,在很久很久以前也是从ROM起步的,无奈还是一脚踏上了Android ...