欢迎来到天天文库
浏览记录
ID:7781393
大小:108.50 KB
页数:6页
时间:2018-02-25
《java内存的详细分析(包括垃圾回收)》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Java内存的详细分析(包括垃圾回收)JVMJava数据结构应用服务器配置管理 1.JAVA 的内存概述:JVM系统中存在一个主内存(MainMemory或JavaHeapMemory),Java中所有变量都储存在主存中,对于所有线程都是共享的。当然,从进程是操作系统资源分配的单位这个角度来看,每个主内存对应于一个进程,多个线程共享该进程的资源(主内存)。每条线程(主要处理用户定义的运算)都有自己的工作内存(WorkingMemory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存
2、中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。他们从主内存中取数据,然后计算,再存入主内存中。当多条线程同时对主存的同一临界资源操作时,就会有线程同步问题;一些是JVM同步机制的大致过程:(1) 获取对象监视器的锁(lock)(2) 清空工作内存数据, 从主存复制变量到当前工作内存, 即同步数据 (readandload)(3) 执行代码,改变共享变量值 (useandassign)(4) 将工作内存数据刷回主存 (storeandwrite)(5) 释放对象监视器的锁 (unlock)注意:
3、其中4,5两步是同时进行的.这些涉及到线程同步问题,在这里就不累述了,简单了解一下。2.从进程和线程的角度认识堆和栈HeapMemory(堆内存):虚拟机的堆内存保存的是对象,类变量以及实例变量,它被所有线程共享,常说的垃圾回收就是对堆内存的回收。Java中堆是由所有的线程共享的一块内存区域,堆用来保存各种JAVA对象,比如数组,线程对象等。也就是上述的主内存(JavaHeapMemory)。StackMemory 栈内存:虚拟机的每一个线程都有一个私有的栈,当一个方法被调用时,下面内容被作为一个Frame(帧
4、)被创建并且被压入栈中: + 局部变量:包括基本数据类型,对象的引用和返回值地址。 + 一个自己的操作栈:帧内局部变量进行运算时使用,也用于传递方法的参数和接受方法的返回值。 + 一个当前方法所在类的Runtimeconstantpool(常量池)的引用。 方法调用完成时,帧出栈,并销毁,无论方法是正常结束还是有未捕获的异常。MethodArea 方法区(或者代码区): 当JVM加载一个class时,将该类的一些信息保存到MethodArea,包括Runtimeconstantpool ,方法数据,方法
5、和构造器代码,域等。Runtimeconstantpool 则包括类名,父类名,静态变量等。MethodArea在逻辑上属于Heap(因为和堆一样是被线程共享的,属于主内存)。不过它垃圾回收与Heap可能不同,取决于JVM的实现。当通过newClass()方式创建一个实例时,JVM在MethodArea寻址到该类的基本信息, 同时进行相关实例的初始化(包括实例变量),存贮在Heap中。3.堆和栈的进一步认识下面我们从JVM的内存管理原理的角度来深入认识堆(Stack)和栈(Heap),并通过这些原理认清Java
6、中静态方法和静态属性的问题。Stack(栈)是JVM的内存指令区。Stack管理很简单,push一定长度字节的数据或者指令,Stack指针压栈相应的字节位移;pop一定字节长度数据或者指令,Stack指针弹栈。Stack的速度很快,管理很简单,并且每次操作的数据或者指令字节长度是已知的。所以Java 基本数据类型,Java 指令代码,常量都保存在Stack中。Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程。它主要用来存储线程执行过程中的局部变量,方法的返回值,以及方法调用
7、上下文。栈空间随着线程的终止而释放。StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么JVM就会抛出此异常,这种情况一般是死递归造成的。Heap(堆)是JVM的内存数据区。Heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在Heap 中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中),在Heap 中分配一定的内存保存对象实例和对象的序列化比较类似。而对象实例
8、在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap 内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。由于Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM中另有一个GC进程,定期扫描Heap ,它根据Stack中保存的4字节对象地址扫描Heap ,定位He
此文档下载收益归作者所有