Java程序在运行时,需要在内存中分配空间。为了提高运行效率,就对数据进行了不同的空间划分。因为每一片区域都有特定的数据处理方式和内存管理方式。

具体分为5种内存空间:

程序计数器:保证线程切换后能恢复到原来的执行位置。

虚拟机栈:(栈内存)为虚拟机执行java方法服务,方法被调用时,创建栈帧-

本地方法栈:为虚拟机执行使用到的Native方法服务

堆内存:存放所有new出来的东西

方法区:存储被虚拟机加载的类信息,常量,静态常量,静态方法等。

运行时常量池(方法区的一部分)

GC对他们的回收:

内存区域中的程序计数器、虚拟机栈、本地方法栈这3个区域随着线程而生,线程而灭;栈中的栈帧随着方法的进入和退出而有条件的执行出栈和入栈的操作。每个栈帧中分配多少内存基本是在类结构确定下来时就已知的。在这个区域不需要过多的考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了。

GC回收的主要对象:Java堆和方法区

一个接口中的多个实现类需要的内存可能不同,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间时才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,GC关注的也是这部分内存。

1.程序计数器:(线程私有)

每隔线程拥有一个程序计数器,在线程创建时创建,指向吓一跳指令的地址

执行本地方法时,其值为undefined。

说的通俗一点,我们知道,Java是支持多线程的,程序先去执行A线程,执行到一半然后去执行B线程,然后又跑去接着执行A线程,那程序是怎么记住A线程已经执行到哪里了呢?这就需要程序计数器了。因此,为了线程切换后能够恢复到正确执行的位置,每条线程都有一个独立的程序计数器,这块属于“线程私有”的内存。

2.Java虚拟机栈(线程私有)

每隔方法被调用的时候会创建一个栈帧,用于存储局部变量表,操作栈,动态链接,方法出口等信息。局部变量表存放的是:编译器可知的基本数据类型,对象引用类型。

每个方法被调用直到执行完的过程,就对应着一个栈帧在虚拟机中从引入到出栈的过程。

在Java虚拟机中,对这个区域规定了两种异常情况:

(1)如果线程请求的栈深度太深,超出了虚拟机所允许的深度,就会出现StackOverFlowError(比如无线递归,因为每一层栈帧都会占用一定空间,erXss规定了栈的最大空间,超出这个值就会报错)

(2)虚拟机栈可以动态扩展,如果扩展到无法申请足够的内存空间,会出现OOM(OutOfMemory)

3.本地方法栈:

(1)本地方法栈与java虚拟机栈做用户非常相似,区别是:java虚拟机栈是为虚拟机执行java方法服务的而本地方法栈则是为虚拟机使用到Native方法服务。

(2)Java虚拟机没有对本地方法栈的使用和数据结构做强制规定,Sun HotSpot虚拟机就把java虚拟机栈和本地方法栈合二为一。

(3)本地方法栈也会抛出StackOverFlowError和OutOfMemoryError

4.Java堆:堆内存

(1)堆是Java虚拟机所管理的内存区域中罪的的一块,java堆是被所有县城共享的内存区域,在java虚拟机启动时创建堆内存的唯一目的就是存放对象实例,几乎所有的对象实例都在堆内存分配。

(2)堆是GC管理的主要区域,从垃圾回收的角度看,由于现在的垃圾收集器都是采用的粉黛手机算法,因此java堆还可以初步细分为新生代和老年代。

(3)Java虚拟机规定,堆可以处于物理上不连续的内存空间中,只要逻辑上连续的即可。在实现的既可以是固定的,也可以是动态扩展的。如果在堆内存没有完成实力分配,并且对大小也无法扩展,就会抛出OutOfMemoryError异常。

5.方法区(线程共享)

(1)用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据。

(2)Sun HotSpot虚拟机把方法区叫做永久带(permanent Generation),方法区中最终要的部分是运行时常量池。

6.运行时常量池:

(1)运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时就会抛出OutOfMemoryError异常。

可以参考http://www.cnblogs.com/smyhvae/p/4748392.html

Java中的内存划分的更多相关文章

  1. java中的内存划分和一个数组的内存图

    内存概述 内存是计算机中的重要原件,临时存储区域,作用是运行程序.我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存   Java虚拟机要运行程序 ...

  2. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  3. 关于Hash集合以及Java中的内存泄漏

    <学习笔记>关于Hash集合以及Java中的内存泄漏 标签: 学习笔记内存泄露hash 2015-10-11 21:26 58人阅读 评论(0) 收藏 举报  分类: 学习笔记(5)  版 ...

  4. java中的内存溢出和内存泄漏

    内存溢出:对于整个应用程序来说,JVM内存空间,已经没有多余的空间分配给新的对象.所以就发生内存溢出. 内存泄露:在应用的整个生命周期内,某个对象一直存在,且对象占用的内存空间越来越大,最终导致JVM ...

  5. 初识:java虚拟机的内存划分

    什么是内存? 内存是计算机中的重要原件,临时存储区域,作用是运行程序.我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存.Java虚拟机要运行程序 ...

  6. Java中JVM内存结构

    Java中JVM内存结构 线程共享区 方法区: 又名静态成员区域,包含整个程序的 class.static 成员等,类本身的字节码是静态的:它会被所有的线程共享和是全区级别的: 属于共享内存区域,存储 ...

  7. java中栈内存与堆内存(JVM内存模型)

    java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...

  8. java中的内存一般分成几部分?

    java中的内存被分成以下四部分: ①.代码区  ②.栈区  ③.堆区   ④.静态区域 栈区:由编译器自动分配释放,存放函数的参数值.局部变量的值等:具体方法执行结束后,系统自动释放JVM内存资源 ...

  9. Java SE之Java中堆内存和栈内存[转/摘]

    [转/摘]1-3Java中堆内存和栈内存 注解:内存(Memory)即 内存储器,主存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器(辅存)交换的数据. Java中把内存分为两种:栈 ...

随机推荐

  1. php读取word里面的内容antiword

    其实是现在一个linux下的扩展 1 先安装  antiword yum antiword install 2 写测试php代码 header("Content-type: text/htm ...

  2. Windows系统日常运维

    WINDOWS系统日常运维 http://www.docin.com/p-677263438.html

  3. load data

    LOAD DATA INFILE 'D:\GX\\mm.txt' REPLACE INTO TABLE mm FIELDS TERMINATED BY ' ' // 以空格为分隔符插入数据,前提是mm ...

  4. 3.mybatis实战教程(mybatis in action)之三:实现数据的增删改查

    转自:https://blog.csdn.net/tangruyi1992/article/details/52583910 前面已经讲到用接口的方式编程.这种方式,要注意的一个地方就是.在User. ...

  5. MySQL命令行学习

    1.登录mysql 本地:mysql -u root -p, 回车后输入密码; 也可以p后不加空格,直接加密码.回车就登录了 远程:mysql -hxx.xx.xx.xx -u -pxxx 2.查看数 ...

  6. SourceTree使用方法

    一 .SourceTree简介 SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端,拥有可视化界面,容易上手操作.同时它也是Mercurial和Subve ...

  7. mysql之MMM高可用方案简介

    MMM(Master-Master Replication Manager for MySQL) MySQL主主复制管理器,提供了MySQL主主复制配置的监控.故障转移和管理的一套可伸缩的脚本套件.在 ...

  8. 趣味编程:FizzBuzz(Swift版)

    func toFizzBuzzExpr(n: Int) -> String { return n % 3 == 0 && n % 5 == 0 ? "FizzBuzz& ...

  9. select 中添加option的注意

    在平时写JS中经常要给Select添加option,如果我们把option中的数据用一个字符串来表示: eg: var strOption='<option>1</option> ...

  10. 类的"魔法"方法

    1. __init__()方法 <1>使用方式 def 类名: #初始化函数,用来完成一些默认的设定 def __init__(): pass 总结1 当创建Car对象后,在没有调用__i ...