[关闭]
@frank-shaw 2015-11-07T08:42:37.000000Z 字数 1537 阅读 1891

JVM的内存基础知识

java.内存


JVM简介

JVM屏蔽了与具体操作系统平台相关的信息,使得java程序只需生成在java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。---跨平台性

一个运行时的java虚拟机实例的天职就是:运行一个java程序。如果同一台计算机上同时运行三个java程序,将会得到三个java虚拟机实例。每个java程序都运行于它自己的java虚拟机实例中。

JVM运行时候的运行时数据区

程序计数器:

它是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器(也就是程序指针嘛)。每条线程都有独立的程序计数器,相互之间不影响。当线程被切换过了一段是时间再被切换回来的话,这个小家伙就会知道线程之前执行到哪里了。

由于Java 虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

如果执行到的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值为空(Undefined).此内存区域是唯一一个在Java虚拟机规范里没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈:

和程序计数器一样,虚拟机栈也是线程私有财产,它的生命周期和线程相同。虚拟机栈描述的是Java**方法执行时的内存模型:每个方法在执行的同时都会创建一个栈帧**用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈到出栈的过程。

本地方法栈:

这个东东和虚拟机栈发挥的作用是相似的,只不过本地方法栈执行的是Native方法服务,而虚拟机栈则是执行java方法服务。它也会抛出StackOverFlowError和OutOfMemoryError异常。

Java堆:

Java堆是所有线程共享的一片内存区域,在虚拟机启动时候创建。此内存区域的唯一目的就是存放对象实例,几乎所有对象实例都在这里分配内存。所有的对象实例以及数组都在堆上面分配。
这个bigBaby是垃圾处理器管理的主要区域,从内存回收的角度来看,由于现在垃圾收集器基本上采取的是分代收集算法,所有Java堆中还可以细分为:新生代和年老代。更新至一点的有Eden空间,From Survivor空间、To Survivor空间等。

设置堆或者栈的大小:
-Xms< size> set initial Java heap size
-Xmx< size> set maximum Java heap size
-Xss< size> set java thread stack size

方法区

方法区和堆一样,是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然两个家伙很相似,但还是要区分开来的,毕竟各自角色不一样啊~

垃圾收集行为在这个区域发生地比较少,但是也不是不发生哈。这区域的内存回收目标主要是针对常量池的回收和对类的卸载。非常有必要,否则会发生Bug的哦。

运行时常量池

运行时常量池是方法区的一部分。Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(非常大的一部分好不好),用户存放编译器生成的各个字面量和符号引用(关于Class文件的信息可以参考《深入理解Java虚拟机》第六章)。这部分内容将在方法区的运行时常量池中存放,存放时间为类加载后。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注