1,java虚拟机的基本结构
(1)类加载子系统:
负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中可能还会存放运行时常量池信息,包括字符串字面量和数字字面量(这部分常量信息是Class文件中常量池部分的内存映射)。
(2)Java堆
在虚拟机启动时创建,是Java程序最主要的内存工作区域。
几乎所有的Java对象实例都存放在Java堆中。
堆空间是所有线程共享的,这是一块与Java应用密切相关的内存空间。
java堆是完全自动化管理的,通过垃圾回收机制,垃圾对象会被自动清理,而不需要显式地释放。
(3)本地方法栈和Java栈:
每一个Java虚拟机线程都有一个私有的Java栈(Java栈是一块线程私有的内存空间)。一个线程的Java栈是线程创建的时候被创建。Java栈中保存着帧信息。Java栈中保存着局部变量、方法参数,同时和Java方法的调用、返回密切相关。
Java栈与数据结构上的栈有着类似的含义,它是一块先进后出的数据结构,只支持出栈和入栈两种操作。在Java栈中保存的主要内容为栈帧。每一次函数调用,都会有一个对应的栈帧被压入Java栈,每一次函数调用结束,都会有一个栈帧出Java栈。
Java方法有两种返回函数的方式,一种是正常的函数返回,使用return指令;另外一种是抛出异常。不管使用哪种方式,都会导致栈帧被弹出。
在一个栈帧中,至少要包含局部变量表、操作数帧和帧数据区。
局部变量表: 保存函数的参数及局部变量。局部变量表中的变量只是在当前函数调用中有效,当函数调用结束后,随着函数栈帧的销毁,局部变量表也随之销毁。
操作数栈:保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。
帧数据区:除了局部变量表和操作数栈外,Java栈帧还需要一些数据来支持常量池解析、正常方法返回和异常处理等。
栈上分配:
是Java虚拟机提供的一项优先技术。基本思想,对于那些线程私有的对象,可以将它们大散分配在栈上,而不是分配在堆上。分配在栈上的好处是可以在函数结束后自行销毁,而不需要垃圾回收器的介入,从而提高系统的性能。
栈上分配的一个技术基础是进行逃逸分析。逃逸分析的目的是判断对象的作用域是否有可能逃逸出函数体。
本地方法栈和Java栈非常相似,最大的不同在于Java栈用于Java方法的调用,而本地方法栈用于本地方法调用。作为Java虚拟机的主要扩展,Java虚拟机允许Java直接调用本地方法。(通常使用C编写)。
(4)方法区
方法区是一块线程共享的内存区域。用于保存系统的类信息,如类的字段、方法、常量池。
(5)Java的NIO库
允许Java程序使用直接内存。直接内存是在Java堆外的、直接向系统申请的内存空间。通常,访问直接内存的速度会优于Java堆。出于性能考虑,读写频繁的场合可能会考虑使用直接内存。由于直接内存在Java堆外,因此它的大小不会直接受限于Xmx指定的最大堆大小,但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。
(6)垃圾回收系统
垃圾回收器可以对方法区、Java堆和直接内存进行回收。
Java堆是垃圾收集器的工作重点。
2,设置Java虚拟机的参数
-Xmx32m 系统最大可用堆空间32MB
-Xms 初始堆空间
-Xss32m 指定线程最大栈空间,这个参数也直接决定了函数调用的最大深度。
-XX:+PrintGC将打印GC日志