目录
1.?前面学习的程序计数器,虚拟机栈和本地方法栈都是线程私有的,堆是线程共享的;
2.?通过 new 关键字,创建的对象都会使用堆内存,其特点是:
1. 代码示例
package cn.itcast.jvm.t1.heap;
import java.util.ArrayList;
import java.util.List;
/**
* 演示堆内存溢出 java.lang.OutOfMemoryError: Java heap space
* -Xmx8m
*/
public class Demo1_5 {
public static void main(String[] args) {
int i = 0;
try {
List<String> list = new ArrayList<>();
String a = "hahaha";
while (true) {
list.add(a); // hahaha, hahahahahaha, hahahahahahahahaha...
a = a + a;
i++;
}
} catch (Throwable e) {
e.printStackTrace();
System.out.println(i);
}
}
}
2. 报错信息?
3. 修改堆内存大小
?修改了堆内存大小后再次运行程序:
?首先通过jps工具查看当前系统中有哪些Java进程,简单使用如下:
jps是 Java Virtual Machine Process Status Tool (Java虚拟机进程状态工具)的缩写,它是JDK提供的一个命令行工具,用于列出当前运行的Java进程信息。jps命令可以显示正在运行的Java进程的进程ID (PID)和主类名称等信息,对于查找和监控Java进程非常有用,特别是在需要与正在运行的Java应用程序进行交互或诊断时,常见的jsp命令选项如下:
(1)jps: 显示系统中的Java进程号和主类名称(不包括主类的包名),如下:
(2)jps -q : 只输出进程ID,而不显示主类名称,如下:
(3)jps -l : 显示完整的主类名称或jar文件名称(如果是通过java -jar 命令进行启动一个项目),如下:
? ? ? ? (3.1)直接启动的java程序或项目(不是通过java -jar 的形式启动的),显示如下:
? ? ? ? (3.2)通过java -jar的方式启动的java服务,如下图显示的是jar包的文件名称:
(4)jps -v?: 可以显示虚拟机启动时的JVM参数,如下:
? ? ? ? (4.1)启动一个通过SpringBoot项目打包的jar,如下:
? ? ? ? (4.2)通过 jps -v 命令查看虚拟机启动参数:如下:
(5)jps -m:?显示虚拟机进程启动时传递给主类 main() 函数的参数,示例如下
? ? ? ? (5.1)一个简单的java程序如下:
package jvm_jps;
public class Test_1 {
public static void main(String[] args) throws InterruptedException {
for (String arg : args) {
System.out.println(arg);
}
Thread.sleep(10000000L);
}
}
? ? ? ? ?(5.2)通过命令行启动这个java程序,如下图所示:
? ? ? ? ?(5.3)然后使用 jps -l -m 查看,如下图:
? ? ? ? (5.4)也可以在启动上述java程序时,指定虚拟机参数,如设置堆内存大小,如下图:
? ? ? ?(5.5) 然后使用 jps -l -v 命令查看启动虚拟机时,传递给虚拟机的参数,如下图:
? ? ? ? ?(5.6)也可以 jsp -l -m -v 一起使用,同时查看传递给main函数的参数和传递给虚拟机的参数,如下图:
????????通过上述的jps命令得到Java进程号后(PID),可以通过jmap工具查看某个java进程的堆内存的使用情况。【jmap -heap pid就可查看某一个java进程的堆内存使用情况】
????????注意:jmap只能查询某个时刻堆内存的占用情况,如果想对堆内存做一个连续的监测,需要使用jconsole或jvirsualvm工具。
控制台输入 jconsole命令,双击你要连接的Java进程,选择不安全的连接,进入界面,如下:
控制台输入jvisualvm命令,如下图所示:
目前只是针对这些工具进行了简要的介绍和使用
场景:
运行一个程序后,通过jps命令查看有哪些java进程,如下图:
使用jmap -heap java进程id 查看当前java进程的堆内存使用情况,如下图:
使用 jconsole工具调出图形化工具进行查看,如下图:
再次使用 jmap -heap 查看此java进程对应的堆内存占用情况,发现老年代占用的堆内存并没有下降,如下图:
此时,就需要另一个工具进行排查,jvisualvm工具,此工具打开的图形化界面可以继续针对上述问题进行排查,如下图:
?分析上面dump出来的堆内存信息,如下图:
?
查看源代码,如下图:?