Java内存分配
2016-03-03 18:58
309 查看
内存分配
1. 程序计数器(线程私有,当前线程执行字节码的行号指示器,Native方法为空Undefined)
2. 虚拟机栈(线程私有,Java方法,每个方法在执行的时候都会创建栈帧,用于储存局部变量表【对象引用+基本数据类型】,操作数栈,动态链接,方法出口等,每个方法的执行和完成,对应着栈帧在虚拟机栈的入栈和出栈)
3. 本地方法栈(线程私有,Native方法)
4. 堆(线程共享,几乎所有对象都在堆分配内存:1.新生代:Eden空间,FromSurvivor空间,ToSurvivor空间 2.老年代 3.线程共享的堆内存还可能会划分出多个线程私有的分配缓冲区TLAB(ThreadLocalAllocationBuffer))
5. 方法区(线程共享,用于储存虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码:class文件保存的信息:类的版本、字段、方法、接口和class的常量池(用于存放编译器生成的各种字面量和符号引用)等,运行时常量池:对于class文件的常量内容,在类被加载时进入方法区的运行时常量池)
6. 直接内存(JDK的NIO的操作,引入了基于通道与缓冲区的IO防辐射,可以使用Native函数库直接分配堆外内存,通过DriectByteBuffer对象作为制片内存的引用进行操作,避免Java堆和Native堆的数据来回拷贝)
对象的创建
对类的初始化和加载创建对象方式:内存绝对规整->指针碰撞(Compact回收算法的分配方式),内存不规整->空闲列表(CMS的Mark-Sweep回收算法的分配方式)
分配对象的时候保证同步:1. CAS+失败重试 2.TLAB(ThreadLocalAllocationBuffer):本地线程缓存
对象内存布局:头信息(header),实例数据,填充对齐
对象的访问定位:
使用句柄:本地变量表->句柄池(堆,到对象实例的指针+到对象类型的指针)->对象实例数据(堆)+对象类型数据(方法区)使用直接指针:本地变量表->对象实例数据(包含对象类型的指针)->对象类型数据(方法区)
区别:
句柄稳定,只需修改句柄指针而不用修改实例数据
直接访问速度快,只需一次访问内存
垃圾回收
垃圾回收动作何时执行?当年轻代内存满时,会引发一次普通GC,该GC仅回收年轻代。需要强调的是,年轻代满是指Eden代满,Survivor满不会引发GC
当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代
当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载
何时会抛出OutOfMemoryException,
并不是内存被耗空的时候才抛出,JVM98%的时间都花费在内存回收,每次回收的内存小于2%
更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC
更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率
相关文章推荐
- TIJ-第三章:操作符
- [JAVA · 初级]:5.以我微观看变量
- java基础之一java环境的搭建
- The first day of learning java
- java回顾之错误处理机制
- 算法代码实现之二分法查找,Java实现
- ubantu14.0.1安装jdk1.7.1
- eclipse安装jetty插件
- TIJ-第一章:对象介绍
- JAVA设计模式之单例模式
- 有关JavaBean的基础知识
- java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.
- Java 技术体系图
- Java 抽象工厂模式
- spring和jsp的数据传递。。。
- IntelliJ使用指南—— 导入Eclipse的Web项目
- javaWeb2.1 XML解析方式之DOM解析
- Spring源码入门——XmlBeanDefinitionReader解析
- Java集合之LinkedList
- 可编辑可自动匹配的联动下拉框实现