内容摘自:深入理解JAVA虚拟机
了解GC和内存分配的原因:
需要排查各种内存溢出,内存泄露问题时,当垃圾收集成为系统达到更高鬓发量的瓶颈时,我们需要对"自动化"的技术,实施必要的监控和调节。
java 内存区域:
运行时数据区域:Method Area,VM Stack ,Native Method Stack,Heap,Program Counter Register (JAVA SE7 规定)
所有区域随着虚拟机的进程启动而存在,有些区域则依赖用户线程的的启动和结束而建立和销毁
所有线程共享Method Area 和Heap
JAVA 虚拟机的多线程实现方式:线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令
Program Counter Register :唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError情况的区域;
VM Stack and Native Method Stack 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈在动态扩展时,无法申请到足够的内存,就会抛出OutOfMemoryError异常
Java heap:所有线程共享的内存区域。虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都要在堆上分配
Method Area:所有线程共享的内存区域。用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。当方法区无法满足内存分配需求时,将抛OutOfMemoryError异常
对象的创建:虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的引用符号,并且检查这个符号引用代表的类是否已被加载,解析和初始化过,如果没有,那必须先执行相应的类加载过程。
虚拟机的类加载机制:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制;
在Java语言中,类型的加载链接和初始化过程都是在程序运行期完成的
优点:编写一个面向接口的应用程序,可以等到运行时在指定实际的实现类,用户可以通过预定义和自定义类加载器,让一个本地的应用程序可以在运行时从网络或者其他地方加载一个二进制流作为程序代码的一部分。Applet,jsp,OSGi都是用了Java运行期类加载特性