Java虚拟机笔记(一)-java内存

时间:2022-12-29 09:14:59

看了深入理解java虚拟机做的一些笔记,觉得对我这个萌新来讲比较有用的,日后再进行完善

程序计数器: 是一块小的内存空间,可以看成一个当前线程所执行的字节码的行号指示器。字节码解释器工作室就是改变这个计数器的值来选取下一条需要执行的字节码指令,比如分支,循环,跳转,异常处理,线程恢复等基础功能。 线程正在运行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,多线程是通过线程轮流切换并分配处理执行时间来实现的,在任何一个确定的时刻,一个处理器只会执行一个线程的指令。为了能恢复线程的位置,每条线程都有一个独立的计数器,各条线程之间的计数器互不影响,独立存储,这块类存区域为线程私有的内存。

java虚拟机栈: 平时说的堆和栈,实际上栈指的就是虚拟机栈,或者说虚拟机中的局部变量表,它存放了编译期可知的各种基本数据类型,对象引用,他所需要的内存空间是在编译期间就已经完成分配,方法运行期间不会被改变

本地方法栈: 和虚拟机栈相似,但是应用与native服务,暂时没搞懂

一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern “C”告知C++编译器去调用一个C的函数。 二.为什么要使用Native Method java使用起来非常方便,然而有些层次的任务用java实现起来不容易,或者我们对程序的效率很在意时,问题就来了。 与java环*交互: 有时java应用需要与java外面的环境交互。这是本地方法存在的主要原因,你可以想想java需要与一些底层系统如操作系统或某些硬件交换信息时的情况。本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解java应用之外的繁琐的细节。 与操作系统交互: JVM支持着java语言本身和运行时库,它是java程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。然而不管怎 样,它毕竟不是一个完整的系统,它经常依赖于一些底层(underneath在下面的)系统的支持。这些底层系统常常是强大的操作系统。通过使用本地方法,我们得以用java实现了jre的与底层系统的交互,甚至JVM的一些部分就是用C写的,还有,如果我们要使用一些java语言本身没有提供封装的操作系统的特性时,我们也需要使用本地方法。 Sun’s Java Sun的解释器是用C实现的,这使得它能像一些普通的C一样与外部交互。jre大部分是用java实现的,它也通过一些本地方法与外界交互。例如:类java.lang.Thread 的 setPriority()方法是用java实现的,但是它实现调用的是该类里的本地方法setPriority0()。这个本地方法是用C实现的,并被植入JVM内部,在Windows 95的平台上,这个本地方法最终将调用Win32 SetPriority() API。这是一个本地方法的具体实现由JVM直接提供,更多的情况是本地方法由外部的动态链接库(external dynamic link library)提供,然后被JVM调用。 java堆:

java堆是所有线程共享的一块区域,,虚拟机启动时创建,存放的全是对象实例,几乎所有的对象实例都在这里进行分配,在虚拟机描述是:所有对象实例以及数组都在堆上分配。 java堆是垃圾收集器管理的主要区域,简称“GC堆”,现在收集器采用分代算法,所有java堆中还可以细分为:新生代和老年代。如果堆没有内存完成实例对象的分配,并且无法扩展就会抛出OutOfMemoryError

方法区:

方法区和堆一样,是线程共享的,存放Class类信息,常量,静态变量以及编译后的代码等数据

运行时的常量池: 是方法区的一部分,用于存放编译期生产成的各种字面量和符号引用。

java堆溢出 java heap space

解决思路: 通过内存映像分析工具,对堆转存储快照惊醒分析先分析是内存泄漏(memory leak)还是内存溢出(memory overflow),如果是内存泄漏,先进一步通过工具查看泄露对象到GC root的引用链,分析他是通过什么样的路径与GCRoot相关联并导致垃圾收集器无法自动回收他们。如果是内存溢出,检查机器内存是否能调大,检查是否存在某些对象生命周期过长,持有状态时间过擦很难过的情况,尝试减少程序运行的内存消耗 -Xms 调节

java栈溢出 在单个线程下,无论是由于栈桢太大还是虚拟机栈容量太小,内存无法分配时都会抛出*Error -XBoss

-XMs + MaxPermSize(方法区容量) + 栈容量 = 内存