虚拟机线程实际问题运行判断我们会给出两个实际案例来进行讲解:
- CPU占用过多
// 我们的项目通常都会运行在Linux服务器上,所以我们下面通过Linux来介绍方法// 首先通过top定位哪个进程对cpu的占用过高top // 然后我们通过ps命令进一步查看哪个线程引起cpu占用率过高ps H -eo pid,tid,%cpu | grep 进程id// 最后我们查看线程具体问题jstack 进程id// 最后我们到我们的项目代码中进行检查会发现问题(可能是死循环之类的)package cn.itcast.jvm.t1.stack;/** * 演示 cpu 占用过高 */public class Demo1_16 {public static void main(String[] args) {new Thread(null, () -> {System.out.println("1...");while(true) {}}, "thread1").start();new Thread(null, () -> {System.out.println("2...");try {Thread.sleep(1000000L);} catch (InterruptedException e) {e.printStackTrace();}}, "thread2").start();new Thread(null, () -> {System.out.println("3...");try {Thread.sleep(1000000L);} catch (InterruptedException e) {e.printStackTrace();}}, "thread3").start();}}
- 程序运行过久没有结果
/*我们采用之前相同的方法来进行判断,一般运行过久没有结果都是发生死锁问题*/package cn.itcast.jvm.t1.stack;/** * 演示线程死锁 */class A{};class B{};public class Demo1_3 {static A a = new A();static B b = new B();public static void main(String[] args) throws InterruptedException {new Thread(()->{synchronized (a) {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (b) {System.out.println("我获得了 a 和 b");}}}).start();Thread.sleep(1000);new Thread(()->{synchronized (b) {synchronized (a) {System.out.println("我获得了 a 和 b");}}}).start();}}
本地方法栈这小节我们来介绍JVM内存结构中的本地方法栈本地方法简介首先我们先来简单介绍一下本地方法:
- JVM属于Java层次的东西,是无法通过Java与底层进行交互
- 这时我们就需要一些采用C,C++语言的方法来与底层进行交互,这种方法就被称为本地方法
- 本地方法大多设置为接口,其返回值类型为native
- 我们常见的本地方法包括有Object中的clone方法,hashCode方法,wait方法等
- 本地方法栈就是一个存储本地方法的栈
- 其原理与虚拟机栈完全相同,只不过里面的栈帧变为了本地方法而已
堆简介首先我们需要先理解什么是堆:
- 堆的本体通常可以被看做一棵完全二叉树的数组
- 通过关键字new创建的对象都会使用堆来存储
- 有垃圾回收机制
- 堆是线程共享的 , 堆中的所有对象都需要考虑线程安全问题
// 在配置运行环境的Environment variables中进行配置(如下修改为256k)-Xmx8m
堆出现内存溢出问题只有一种情况就是创建对象过多:/*正常情况下,我们的创建的对象在不使用的情况下就会被自动垃圾回收但如果出现异常,导致我们不断创建新对象且保存就对象就会导致堆内存溢出*/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 = "hello";while (true) {list.add(a); // 这里将旧对象保存下来a = a + a;// 这里不断创建新对象i++;}} catch (Throwable e) {e.printStackTrace();System.out.println(i);}}}
堆内存问题诊断我们在正常运行中堆的内存占有是非常重要,因此JVM为我们提供了四种方法来检查堆内存问题首先我们给出用于诊断堆内存问题的参考代码:
package cn.itcast.jvm.t1.heap;/** * 演示堆内存 */public class Demo1_4 {public static void main(String[] args) throws InterruptedException {// 第一阶段:没有对象System.out.println("1...");Thread.sleep(30000);// 第二阶段:制造一个对象,占用堆byte[] array = new byte[1024 * 1024 * 10];System.out.println("2...");Thread.sleep(20000);// 第三阶段:释放对象,并进行垃圾回收,这时堆变小array = null;System.gc();System.out.println("3...");Thread.sleep(1000000L);}}
我们的JVM为我们提供了四种方法来检测堆的状况:- jps工具
// jps用于查看当前系统中有哪些java进程// 我们直接在IDEA的输入台输入即可jps
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 【lwip】08-ARP协议一图笔记及源码实现
- 小米笔记本Pro15增强版评测_小米笔记本Pro15增强版评测表现
- 用一台笔记本电脑如何赚钱(笔记本电脑赚钱的办法)
- 四 【单片机入门】应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
- 笔记本电脑CF中烟雾头怎么调(win10cf新版本烟雾保护头怎么调)
- 笔记本电脑配置高低怎么区分(笔记本电脑看什么配置判断好坏)
- pytorch、paddlepaddle等环境搭建 深度学习环境搭建常用网址、conda/pip命令行整理
- 三十九 Java开发学习----SpringBoot整合mybatis
- Nacos基本学习
- 数据科学学习手札146 geopandas中拓扑非法问题的发现、诊断与修复