`
VerRan
  • 浏览: 459104 次
  • 性别: Icon_minigender_1
  • 来自: 陕西.西安
社区版块
存档分类
最新评论

利用 Java dump 进行 JVM 故障诊断

阅读更多

转自:http://jimmyleeee.blog.163.com/blog/static/930961820091183527621/?fromdm&isFromSearchEngine=yes

引言

对于大型 java 应用程序来说,再精细的测试都难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。JVM 能够记录下问题发生时系统的运行状态并将其存储在转储(dump)文件中,从而为我们分析和诊断问题提供了重要的依据。常见的转储文件包括 Java Dump, Heap dump 和 System dump。这里我们主要介绍 Java dump 在 JVM 故障诊断中的应用。

Java dump,也叫做 Thread dump,是 JVM 故障诊断中最重要的转储文件之一。JVM 的许多问题都可以使用这个文件进行诊断,其中比较典型的包括线程阻塞,CPU 使用率过高,JVM Crash,堆内存不足,和类装载等问题。作为一款轻量级(与 Heap dump 和 System dump 相比)的转储文件,Java dump 的确是我们诊断 JVM 问题的首选。本文将系统的介绍使用 Java dump 进行 JVM 故障诊断的方法和技巧,希望能够为大家提供一些帮助。

 




回页首


Java dump 文件的格式和内容

Java dump 通常是文本格式(.txt),因此可以通过一般的文本编辑器进行阅读,阅读时需要注意段与行的格式:

段格式

为了便于大家的分析,Java dump 的每一段的开头,都会用“-----”与上一段明显的区分开来。而每一段的标题也会用“=====”作为标识,这样我们就能够很容易的找到每一段的开头和标题部分(如清单 1)。


清单 1. Java dump 段标题示例

NULL --------------------------------
0SECTION TITLE subcomponent dump routine
NULL ===============================

 

行格式

Java dump 文件中,每一行都包含一个标签,这个标签最多由 15 个字符组成(如清单2中所示)。其中第一位数字代表信息的详细级别(0,1,2,3,4),级别越高代表信息越详细;接下来的两个字符是段标题的缩写,比如,“CI” 代表 “Command-line interpreter”,“CL” 代表 “Class loader”,“LK” 代表 “Locking”,“ST” 代表 “Storage”,“TI” 代表 “Title”,“XE” 代表 “Execution engine”等等;其余部分为信息的概述。


清单 2. Java dump 行标签和内容示例

1TISIGINFO Dump Event "uncaught" (00008000) Detail "java/lang/OutOfMemoryError" received

 

不同版本的 JVM 所产生的 Java dump 的格式可能会稍有不同,但基本上都会包含以下几个方面的内容:

  • TITLE 信息块:描述 JAVA DUMP 产生的原因,时间以及文件的路径。
  • GPINFO信息块:GPF 信息。
  • ENVINFO 信息块:系统运行时的环境及 JVM 启动参数。
  • MEMINFO 信息块:内存的使用情况和垃圾回收记录。
  • LOCKS 信息块:用户监视器(Monitor)和系统监视器(Monitor)。
  • THREADS信息块:所有 java 线程的状态信息和执行堆栈。
  • CLASSES信息块:类加载信息。





回页首


利用 Java Dump 进行 JVM 故障诊断

由于 Java dump 文件包含的内容比较广泛,因此 JVM 的很多问题都可以通过 java dump进行诊断。这些问题主要包括线程阻塞,CPU 使用率过高,JVM Crash,堆内存不足,和类装载等问题。

诊断线程阻塞问题

线程阻塞是我们在 java 多线程编程中经常遇到的问题。由于对后端有限资源的争用以及过度同步等问题,经常会发现 Java dump 中某个资源(锁对象)下有太多的线程处于等待状态,这时候我们通常需要从以下三个方面去诊断这个问题:

  • 这个锁存在的目的是什么?有没有可能去掉这个锁或者缩小这个锁保护的范围,从而减少线程等待问题发生的几率。
  • 有哪些线程需要用到这个锁,有没有可能改用其它更好的替代方案。
  • 当前哪个线程正在持有这个锁,持有的时间是多长,有没有可能缩短持有的时间。

比线程阻塞更严重的是死锁问题,当两个以上的线程互相等待对方的锁,从而形成一个环的时候,就会发生死锁。关于如何使用 Java dump 诊断死锁的问题,请参考 在 WebSphere Application Server V6.1 应用程序中跟踪死锁 一文,该文对此问题做了较为详细的介绍。

诊断 JVM Crash 问题

JVM Crash 是我们所碰到的最棘手的问题之一,它对整个系统的影响是致命的,并且总是让人防不胜防。导致 JVM 崩溃的原因有很多,通常都是一些底层的错误。比如 JVM 本身的 bug,错误的 JNI 调用,第三方原生模块(比如数据库驱动程序)中的 bug 等。JVM崩溃的原因复杂,并且大多都难以重现,所以诊断起来有一定的难度。

一般来说,JVM 崩溃的时候,系统一般会自动产生一个 Java dump 文件(JVM 默认的设置参数就会触发)。这个 Java dump 会帮我们记录下 JVM 崩溃的原因,相关的信息会记录在 TITLE 信息块,GPINFO 信息块和 THREADS 信息块中。

  • TITLE 信息块:用于确认问题产生的原因,即是否是由于一些底层错误而导致 JVM Crash。
  • GPINFO 信息块:用于查看问题的详细信息和问题定位。
  • THREADS信息块:用于了解问题线程的运行情况。

下面我们通过一个具体的例子来介绍 JVM Crash 问题的诊断方法。TestJni 是一个简单的 Java 应用,它通过 JNI 调用本地代码 CallJin.dll 中的 doSomeThing() 函数。


清单 3. 在 TestJni 类中调用 CallJin.dll 中的函数

package test;
public class TestJin {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TestJin testObj = new TestJin();
        testObj.work();
    }
    public void work() {
        CallJni.doSomeThing();
    }
}
package test;
public class CallJni {
    static
    {
    System.loadLibrary("CallJni");
    System.out.println("Dll Loaded");
    }
    public native static void doSomeThing();
}

 

CallJin.dll 是 C++ 编写得本地库,其源代码如清单 3 所示:


清单 4. CallJni.dll 的 C++ 实现代码

#include <com_test_CallJni.h>
/*
 * Class:     com_test_CallJni
 * Method:    doSomeThing
 */
JNIEXPORT void JNICALL Java_test_CallJni_doSomeThing
  (JNIEnv *, jclass){
      int *i;
      *i = 100;
  }

 

在这段 C++ 代码中,整形指针 I 还没有分配空间就被赋了值,这是一个非常严重的错误。当然 java 应用程序员并不知道这一点,并且在 java 应用程序中调用了 doSomeThing() 这个 JNI 函数。结果导致 JVM 发生了崩溃。

在这段 C++ 代码中,整形指针 I 还没有分配空间就被赋了值,这是一个非常严重的错误。当然 java 应用程序员并不知道这一点,并且在 java 应用程序中调用了 doSomeThing() 这个 JNI 函数。结果导致 JVM 发生了崩溃。

下面是 JVM 崩溃时,系统为我们生成的 Java dump 文件的片断。


清单5. Java dump 文件片断

NULL           ----------------------------------------------
0SECTION       TITLE subcomponent dump routine
NULL           ===============================
1TISIGINFO     Dump Event "gpf" (00002000) received 
1TIDATETIME    Date:                 2008/11/12 at 20:45:24
1TIFILENAME Javacore filename: 
C:\eclipse\workspace\Serviceability\TestApps\SampleLeak\TestJin\
javacore.20081112.204522.5656.txt

 

从 TITLE 信息块中我们可以看到,这个 java 是由一个 "gpf" 事件触发的,GPF 是 General Protection Fault 的缩写,表明应用程序发生了一般性保护错误,这种错误常常导致 JVM 突然崩溃。

除了 "gpf" 之外,Java dump 还可能由如下事件触发(清单 6)。


清单 6. 常见 Java dump 触发事件

user       SIGQUIT signal (Ctrl-Brk on Windows, Ctrl-\ on Linux, Ctrl-V on z/OS)
abort      a controlled crash, as triggered by the abort() system call
vmstart    the VM has finished initialization
vmstop     the VM is about to shutdown
load       a new class has been loaded
unload     a classloader has been unloaded
throw      a Java exception has been thrown
catch      a Java exception has been caught
uncaught   a Java exception was not handled by the application
thrstart    a new thread has started
thrstop    an old thread has stopped
blocked    a thread is blocked entering a monitor
fullgc      garbage collection has started

 

从 TITLE 信息块,我们只能初步了解问题产生的原因,如果要进一步了解问题的详细信息,还要查看 GPINFO 信息块(清单 7):


清单7. GPINFO 信息块

NULL           ----------------------------------------------
0SECTION       GPINFO subcomponent dump routine
NULL           ================================
2XHOSLEVEL     OS Level         : Windows XP 5.1 build 2600 Service Pack 3
2XHCPUS        Processors -
3XHCPUARCH       Architecture   : x86
3XHNUMCPUS       How Many       : 2
NULL           
1XHEXCPCODE    J9Generic_Signal_Number: 00000004
1XHEXCPCODE    ExceptionCode: C0000005
1XHEXCPCODE    ExceptionAddress: 412E136E
1XHEXCPCODE    ContextFlags: 0001003F
1XHEXCPCODE    Handler1: 7EFB04E0
1XHEXCPCODE    Handler2: 7F057A80
1XHEXCPCODE    InaccessibleAddress: CCCCCCCC
NULL           
1XHEXCPMODULE  Module: 
C:\eclipse\workspace\Serviceability\TestApps\SampleLeak\TestJin\CallJni.dll
1XHEXCPMODULE  Module_base_address: 412D0000
1XHEXCPMODULE  Offset_in_DLL: 0001136E
NULL           
1XHFLAGS       VM flags:00040000
NULL

 

GPINFO 信息块中我们可以找到问题的异常代码,DE>ExceptionCode: C0000005DE> 代表内存访问错误或者非法的内存操作。DE>Module: C:\eclipse\workspace\Serviceability\TestApps\TestJin\CallJni.dllDE> 指明了发生问题的原生模块。 CallJni.dll 这个动态连接库是我们自己的 JNI 代码,因此很容易发现问题的所在。在一个复杂的 java 运行环境下,很多时候异常是在第三方的代码库中产生的,我们没有办法查看源代码中的问题,这时候只能通过文件名中的一些关键字来推测问题发生的位置,这些关键字包括(清单 8):


清单 8. 需要注意的关键字

GC = garbage collection/collector (how Java frees memory)
JIT = just-in-time compiler, a feature of JVM 
JDBC = Java feature for database access
ORB = object request broker, lower layer of app server
JMS = java messaging service, feature of web server or add-on

 

例如,Module: C:\JDK\IBM\java1.5.0\jre\bin\j9jit23.dll

说明 JIT 模块发生问题,用户可以使用 JITC_COMPILEOPT 变量的 SKIP 选项禁用对当前方法进行 JIT 编译,然后再对系统的运行情况进行进一步的跟踪。

DE>JITC_COMPILEOPT=SKIP{failingPackage/failingClass}{failingMethod}DE>

除此之外,查看 THREADS 信息块中当前线程的执行堆栈也有助于我们对问题的诊断。从清单 9 我们可以看到 main 线程在执行 CallJni.doSomeThing 方法数的过程中发生了问题,据此我们可以返回源代码中查找相应的方法,进而确定问题的根源。


清单 9. Threads 信息块

NULL           ----------------------------------------------------
0SECTION       THREADS subcomponent dump routine
NULL           =================================
NULL            
1XMCURTHDINFO  Current Thread Details
NULL           ----------------------
3XMTHREADINFO  "main" (TID:0x408C7C00, sys_thread_t:0x00366278, state:R, 
                       native ID:0x000016CC) prio=5
4XESTACKTRACE          at test/CallJni.doSomeThing(Native Method)
4XESTACKTRACE          at test/TestJin.work(TestJin.java:16)
4XESTACKTRACE          at test/TestJin.main(TestJin.java:11)
NULL

 

诊断 CPU 利用率过高问题

CPU 使用率过高可能是由于某些线程陷入了死循环或者执行了不适当的操作引起的,其诊断方法就是将这些线程找出来,修正问题或者进行代码优化。由于 Java Dump 中并没有包含各线程的资源使用情况,因此我们需要结合其他的操作系统命令/工具(prstat、top、pslist 等等),将 CPU 使用率较高的线程映射到 Java Dump 中,并分析这些线程的状态以及可能发生的问题。

从下面这段 PSList 的输出结果中我们可以看到 jvm 内部每个线程消耗的总的“用户时间”和“内核时间”,比较几次 PSList 的输出结果,我们就能从中找出那些 CPU 使用时间显著增加的线程,再将这些线程的 TID 映射到Java Dump中,进而查看问题线程的详细信息。


清单 10. PSList 的输出结果

pslist -d <Java PID>

Tid Pri    Cswtch            State     User Time   Kernel Time   Elapsed Time
2908   8      2025   Wait:Executive  0:00:00.359   0:00:01.312    1:48:08.046
4344  15       157     Wait:UserReq  0:00:00.218   0:00:00.015    1:48:07.921
4836  15    415456     Wait:UserReq  0:00:00.000   0:00:00.000    1:48:07.921
2496   8         1     Wait:UserReq  0:00:00.000   0:00:00.000    1:48:07.796
4648   9         1     Wait:UserReq  0:00:00.000   0:00:00.000    1:48:07.796
3116   9         7     Wait:UserReq  0:00:00.000   0:00:00.000    1:48:07.796
5268   8       189     Wait:UserReq  0:00:00.015   0:00:00.000    1:48:07.796
5220   7   6991523          Running  1:47:42.031   0:00:01.218    1:48:05.593
3932   9         2     Wait:UserReq  0:00:00.000   0:00:00.000    1:48:05.125

 

与线程死锁问题不同,在分析 CPU 利用率过高的问题时,我们不需要关心那些处于等待状态的线程,因为线程处于等待状态不需要消耗 CPU 资源。我们关注的重点应该是 THREADS 信息块中那些正在运行(state:R 状态)的线程。很多时候为了分析线程状态的一些变化,我们需要对比多个 Java Dump 文件,看哪些线程状态发生了变化,哪些一直在执行相同的函数,从而找出那些可疑的问题线程。

诊断堆内存不足问题

除了 Thread 相关的信息外,Java Dump 还包含 Memory 和 GC 等方面的信息,虽然这些信息不像 Heap Dump 和 VerboseGC 那么详细,但对于一些比较简单的问题定位还是很有帮助的。例如,下面的 Java dump 清单中,DE>Dump Event "uncaught" (00008000) Detail "java/lang/OutOfMemoryError" receivedDE> 告诉我们问题是由于内存溢出引起的,并且从 MEMINFO 信息块中可以找到当前堆中的空间使用情况, 1ffa0 的剩余空间说明系统的可用堆内存已经严重不足了,需要我们扩大堆内存的大小或者修改应用程序使其占用更少的内存。


清单 11. MEMINFO 信息块

NULL         ----------------------------------------------------
0SECTION     TITLE subcomponent dump routine
NULL         ===============================
1TISIGINFO  Dump Event "uncaught" (00008000) Detail "java/lang/OutOfMemoryError" received 
1TIDATETIME  Date:                 2008/04/20 at 19:13:50
1TIFILENAME  Javacore filename:    
            c:\Serviceability\AppServer\profiles\AppSrv01\javacore.20080420.185326.948.txt

NULL           ----------------------------------------------------
0SECTION       MEMINFO subcomponent dump routine
NULL           =================================
1STHEAPFREE    Bytes of Heap Space Free: 1ffa0 
1STHEAPALLOC   Bytes of Heap Space Allocated: 40000000

 

类加载问题

常见的类加载问题包括: ClassNotFoundException,Jar 包冲突以及由类装入引发的其他问题(例如 jdk 1.4 中的内存碎片问题) Java Dump 文件的 Classes 信息块的格式如清单中示,这些信息可以帮我们确定以下问题:

  • 当前系统中有哪些 Class 文件被加载进来。
  • 确认某个 Class 是否被正确的 ClassLoader 所加载,即不同的 ClassLoader 之间是否有 Jar 包冲突。
  • 已经加载的 Class 的个数。在IBM Jre1.4中,我们可以参考系统中 Class 的个数来设置 KCluster 的大小。


清单 12. CLASSES 信息块

NULL     ---------------------------------------------------------
0SECTION       CLASSES subcomponent dump routine
NULL           =================================
1CLTEXTCLLOS       Classloader summaries
1CLTEXTCLLSS           12345678:
                       1=primordial,2=extension,3=shareable,4=middleware,5=system,
                       6=trusted,7=application,8=delegating
2CLTEXTCLLOADER        p---st-- Loader *System*(0x008DA0B0)
3CLNMBRLOADEDLIB        Number of loaded libraries 3
3CLNMBRLOADEDCL            Number of loaded classes 347
2CLTEXTCLLOADER        -x--st-- Loader sun/misc/Launcher$ExtClassLoader(0x008E5E38), 
                       Parent *none*(0x00000000)
3CLNMBRLOADEDLIB        Number of loaded libraries 0
3CLNMBRLOADEDCL            Number of loaded classes 0
2CLTEXTCLLOADER        -----ta- Loader sun/misc/Launcher$AppClassLoader(0x008EF3E0), 
                       Parentsun/misc/Launcher$ExtClassLoader(0x008E5E38)
3CLNMBRLOADEDLIB        Number of loaded libraries 0
3CLNMBRLOADEDCL            Number of loaded classes 2
1CLTEXTCLLIB       ClassLoader loaded libraries
2CLTEXTCLLIB          Loader *System*(0x008DA0B0)
3CLTEXTLIB               C:\JDK\IBM\java1.5.0\jre\bin\java
3CLTEXTLIB               C:\JDK\IBM\java1.5.0\jre\bin\jclscar_23
3CLTEXTLIB               C:\JDK\IBM\java1.5.0\jre\bin\zip
1CLTEXTCLLOD       ClassLoader loaded classes
2CLTEXTCLLOAD          Loader *System*(0x008DA0B0)
3CLTEXTCLASS               java/io/ByteArrayOutputStream(0x40D40098)
3CLTEXTCLASS               sun/nio/ByteBuffered(0x40D40330)
3CLTEXTCLASS               java/lang/ref/PhantomReference(0x40DB9360)
3CLTEXTCLASS               sun/misc/Cleaner(0x40DB94A8)





回页首


常见问题

关于 Java dump,下面是一些有可能让你产生困惑的问题:

为什么发生 JVM Crash 时,JVM 没有自动生成 Java dump 文件?

答:这种情况大多与系统的环境变量或者 JVM 启动参数的设置有关,比如设置了 DE>DISABLE_JAVADUMP=true,IBM_NOSIGHANDLER=trueDE> 等等,因此可以首先检查系统设置和 JVM 启动参数。当然也不排除因为一些不确定因素导致 JVM 无法产生 Java dump,虽然这种可能性比较小。

JVM 在生成 Java dump 的同时也生成了 Heap dump,它们之间有没有什么联系?

答:有,但是关系不大。因为 java dump 主要反映的是线程的运行状态,而 Heap dump 则主要反映对象之间的引用关系,所以两者之间没有太大的联系。有时候我们可以通过锁对象或者 Class 对象的起始地址找到它在 Heap dump 中的位置,但大多数时候这对故障诊断并没有多大意义。

为什么有些 java dump 的锁没有 owner?

答:并不是所有的锁都被其它线程持有,有些锁是用作主动等待的,比如 sleep() ,wait(),join() 等,这些锁并没有被其它线程占用,被它阻塞的线程只是在等待通知,即 “Waiting to be notified”。从线程状态上看,这些锁一般都处于 “CW” 状态。

Java Dump 中的很多线程处于 state:CW 和 state:B 状态,它们之间有何区别?

答:两者都处于等待状态。不同是:

CW - Condition Wait – 条件等待. 这种等待一般是线程主动等待或者正在进行某种 IO 操作,而并非等待其它线程释放资源。比如 sleep() ,wait(),join() 等方法的调用。

B – Blocked – 线程被阻塞,与条件等待不同,线程被阻塞一般不是线程主动进行的,而是由于当前线程需要的资源正在被其他线程占用,因此不得不等待资源释放以后才能继续执行,例如 synchronized 代码块。

为什么我在 PsList 里看到的线程无法映射到 Java dump 中?

答:由于很多操作系统工具和命令输出的线程的 TID 都是十进制的,映射到 Java dump 时首先要将其转换为十六进制数字,然后再到 Java dump 中查找对应的 native ID。Java dump 中每个线程都有两个ID, 一个是 java 线程的TID, 另一个是对应操作系统线程的 native ID。

阅读 Websphere Appliaction Server 产生的 Java dump 文件有没有什么特别的技巧?

答:对于 WAS 应用程序来说,线程信息往往要比一般的应用程序复杂的多。记住一些常见的 ThreadName 可以帮助我们更好的理解应用程序的运行状态,例如:

线程名 线程信息
Web Container: # WAS web container *
Alarm Thread # handles timer processing
Session.Transports.Threads:### servlet threads for processing HTTP requests
ORB.thread.pool:### ORB thread (ORB data)
P=437206:O=0:
StandardRT=19027:LocalPort=9001:RemoteHost=hostname.ibm.com:RemoteP
an ORB thread for receiving an EJB request or other ORB request
Thread-##
分享到:
评论

相关推荐

    【9493】基于springboot+vue的美食信息推荐系统的设计与实现.zip

    技术选型 【后端】:Java 【框架】:springboot 【前端】:vue 【JDK版本】:JDK1.8 【服务器】:tomcat7+ 【数据库】:mysql 5.7+ 项目包含前后台完整源码。 项目都经过严格调试,确保可以运行! 具体项目介绍可查看博主文章或私聊获取 助力学习实践,提升编程技能,快来获取这份宝贵的资源吧! 在当今快速发展的信息技术领域,技术选型是决定一个项目成功与否的重要因素之一。基于以下的技术栈,我们为您带来了一份完善且经过实践验证的项目资源,让您在学习和提升编程技能的道路上事半功倍。以下是该项目的技术选型和其组件的详细介绍。 在后端技术方面,我们选择了Java作为编程语言。Java以其稳健性、跨平台性和丰富的库支持,在企业级应用中处于领导地位。项目采用了流行的Spring Boot框架,这个框架以简化Java企业级开发而闻名。Spring Boot提供了简洁的配置方式、内置的嵌入式服务器支持以及强大的生态系统,使开发者能够更高效地构建和部署应用。 前端技术方面,我们使用了Vue.js,这是一个用于构建用户界面的渐进式JavaScript框架。Vue以其易上手、灵活和性能出色而受到开发者的青睐,它的组件化开发思想也有助于提高代码的复用性和可维护性。 项目的编译和运行环境选择了JDK 1.8。尽管Java已经推出了更新的版本,但JDK 1.8依旧是一种成熟且稳定的选择,广泛应用于各类项目中,确保了兼容性和稳定性。 在服务器方面,本项目部署在Tomcat 7+之上。Tomcat是Apache软件基金会下的一个开源Servlet容器,也是应用最为广泛的Java Web服务器之一。其稳定性和可靠的性能表现为Java Web应用提供了坚实的支持。 数据库方面,我们采用了MySQL 5.7+。MySQL是一种高效、可靠且使用广泛的关系型数据库管理系统,5.7版本在性能和功能上都有显著的提升。 值得一提的是,该项目包含了前后台的完整源码,并经过严格调试,确保可以顺利运行。通过项目的学习和实践,您将能更好地掌握从后端到前端的完整开发流程,提升自己的编程技能。欢迎参考博主的详细文章或私信获取更多信息,利用这一宝贵资源来推进您的技术成长之路!

    (源码)基于Spring、Struts和Hibernate的OA系统.zip

    # 基于Spring、Struts和Hibernate的OA系统 ## 项目简介 本项目是一个基于Spring、Struts和Hibernate框架的办公自动化(OA)系统。该系统主要用于企业内部的日常办公管理,包括用户登录、组织管理、权限管理等功能。系统前端使用现成的模板和JavaScript、jQuery技术,后端通过Struts、Hibernate和Spring框架实现业务逻辑和数据持久化。 ## 项目的主要特性和功能 ### 登录模块 防止多设备登录系统能够检测到同一账号在不同设备上的登录情况,并在检测到异地登录时通知用户并强制下线。 WebSocket支持使用WebSocket技术实现实时通知功能。 ### 组织管理模块 部门管理支持部门的增删改查操作,包括查看部门信息、职位信息和员工数量。 用户管理支持用户的增删改查操作,包括指定用户所在部门、职位和角色。 角色管理支持角色的增删改查操作,包括查看角色权限和修改角色权限。

    基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目)

    基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目),该项目是个人毕设项目,答辩评审分达到98分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目)基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目)基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目)基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目)基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高分项目)基于MySQL、express框架、Vue3的光谷智慧交通系统源码+数据库+文档说明(高

    open3d python 给点云每个点设置不同的颜色

    open3d python 给点云每个点设置不同的颜色

    【电磁】基于matlab具有Mur吸收边界的区域的二维FDTD【含Matlab源码 9136期】.mp4

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    HengCe-18900-2024-2030中国室内木门市场现状研究分析与发展前景预测报告-样本.docx

    HengCe-18900-2024-2030中国室内木门市场现状研究分析与发展前景预测报告-样本.docx

    (源码)基于ASP.NET Web API的供应链管理系统.zip

    # 基于ASP.NET Web API的供应链管理系统 ## 项目简介 供应链管理系统(SCM)是一个基于ASP.NET Web API框架开发的企业级应用,旨在帮助企业高效管理供应链中的各个环节。系统涵盖了供应商管理、采购管理、库存管理、订单管理等多个模块,通过API接口实现数据的增删改查操作,确保供应链的顺畅运作。 ## 项目的主要特性和功能 1. 供应商管理 供应商信息的增删改查操作。 供应商联系人管理。 供应商评级和分类管理。 2. 采购管理 采购订单的创建、编辑和删除。 采购产品的状态管理。 采购合同的生成和管理。 3. 库存管理 库存产品的入库和出库管理。 库存状态的实时监控。 4. 订单管理 订单的创建、编辑和删除。 订单状态的跟踪和管理。 5. 用户管理 用户登录和权限管理。 用户角色的分配和管理。

    基于SpringBoot的“学生考勤管理系统”的设计与实现(源码+数据库+文档+PPT).zip

    系统主要包括首页,个人中心,学生管理,教师管理,班级信息管理,课程信息管理,签到信息管理,考勤信息管理,请假信息管理,考勤统计管理等功能模块。

    维特协议标准精度示例程序c.zip

    c语言

    DICOM文件+DX放射平片-数字X射线图像DICOM测试文件

    DICOM文件+DX放射平片—数字X射线图像DICOM测试文件,文件为.dcm类型DICOM图像文件文件,仅供需要了解DICOM或相关DICOM开发的技术人员当作测试数据或研究使用,请勿用于非法用途。

    C#ASP.NET仓储管理系统源码数据库 SQL2008源码类型 WebForm

    ASP.NET仓储管理系统源码 一、 程序说明 该程序大部分使用于生产制造厂,其中结合了制造厂的采购,销售,生产等. 开源部分是仓库系统后台管理系 统, 在给客户实施的过程中利用到了很多硬件设备, 设计到Wince系统,Android系统等PDA设备,各种打印 机,条码打印机,感应设备等,而且这些可能在整个项目中占据主导,而后台管理系统只是辅助作用的。 该程序使用的.NET MVC开发,大量使用到了jQuery,以及Bootstrap。 数据库使用了SQL Server.

    【小程序毕业设计】面向文艺影视社群的微信小程序源码(完整前后端+mysql+说明文档).zip

    环境说明: 开发语言:Java/php JDK版本:JDK1.8 数据库:mysql 5.7及以上 数据库工具:Navicat11及以上 开发软件:eclipse/idea 小程序框架:uniapp/原生小程序 开发工具:HBuilder X/微信开发者

    Skia-macOS-Release-arm64.zip

    Skia-macOS-Release-arm64.zip aseprite 安装所需依赖安装包

    中国品牌日研究特辑-数字经济时代下中国品牌高质量发展之用户趋势.pdf

    中国品牌日研究特辑-数字经济时代下中国品牌高质量发展之用户趋势.pdf

    生成xcinsphfs0exefsromfscertifateticket转储从任天堂Switch游戏卡和安装的SDe.zip

    c语言

    一个基于qt开发的包含各种基础图像处理技术的桌面应用,图像处理算法基于halcon,有直接调用halcon脚本和执行halcon

    一个基于qt开发的包含各种基础图像处理技术的桌面应用,图像处理算法基于halcon,有直接调用halcon脚本和执行halcon C++代码方式。 导入图片,预处理,滤波,边缘检测,阈值分割,形态学变换,图像增强,图像变换,

    【9312】基于Springboot+vue的精品水果线上销售网站的设计与实现.zip

    技术选型 【后端】:Java 【框架】:springboot 【前端】:vue 【JDK版本】:JDK1.8 【服务器】:tomcat7+ 【数据库】:mysql 5.7+ 项目包含前后台完整源码。 项目都经过严格调试,确保可以运行! 具体项目介绍可查看博主文章或私聊获取 助力学习实践,提升编程技能,快来获取这份宝贵的资源吧! 在当今快速发展的信息技术领域,技术选型是决定一个项目成功与否的重要因素之一。基于以下的技术栈,我们为您带来了一份完善且经过实践验证的项目资源,让您在学习和提升编程技能的道路上事半功倍。以下是该项目的技术选型和其组件的详细介绍。 在后端技术方面,我们选择了Java作为编程语言。Java以其稳健性、跨平台性和丰富的库支持,在企业级应用中处于领导地位。项目采用了流行的Spring Boot框架,这个框架以简化Java企业级开发而闻名。Spring Boot提供了简洁的配置方式、内置的嵌入式服务器支持以及强大的生态系统,使开发者能够更高效地构建和部署应用。 前端技术方面,我们使用了Vue.js,这是一个用于构建用户界面的渐进式JavaScript框架。Vue以其易上手、灵活和性能出色而受到开发者的青睐,它的组件化开发思想也有助于提高代码的复用性和可维护性。 项目的编译和运行环境选择了JDK 1.8。尽管Java已经推出了更新的版本,但JDK 1.8依旧是一种成熟且稳定的选择,广泛应用于各类项目中,确保了兼容性和稳定性。 在服务器方面,本项目部署在Tomcat 7+之上。Tomcat是Apache软件基金会下的一个开源Servlet容器,也是应用最为广泛的Java Web服务器之一。其稳定性和可靠的性能表现为Java Web应用提供了坚实的支持。 数据库方面,我们采用了MySQL 5.7+。MySQL是一种高效、可靠且使用广泛的关系型数据库管理系统,5.7版本在性能和功能上都有显著的提升。 值得一提的是,该项目包含了前后台的完整源码,并经过严格调试,确保可以顺利运行。通过项目的学习和实践,您将能更好地掌握从后端到前端的完整开发流程,提升自己的编程技能。欢迎参考博主的详细文章或私信获取更多信息,利用这一宝贵资源来推进您的技术成长之路!

    C#固定资产管理系统源码(带条码打印)数据库 SQL2008源码类型 WinForm

    固定资产管理系统源码(带条码打印) 功能介绍 1.基本信息管理:包括资产分类,基本资料,资产编号规则,保存列间距和选择资产显示列等功能; 2.固定资产管理:包括资产增加,资产更新,资产删除,资产清理,资产清理查询和资产折旧核算 3.数据维护管理:包系统数据初始化,系统数据备份/恢复等功能; 4.系统维护管理:包括本单位信息和操作员管理等功能; 5.系统辅助工具:包括计算器和记事本等功能; 6.条码打印:对条码进行打印等功能;

    【Unity车辆控制插件】Realistic Car Controller轻松创建逼真的汽车模拟或赛车游戏

    文件名:Realistic Car Controller v3.95.unitypackage Realistic Car Controller 是一款在 Unity 中用于实现高度真实感的车辆控制和物理效果的插件。它提供了一整套车轮物理、动力学、碰撞检测以及其他重要功能,能够帮助开发者轻松创建逼真的汽车模拟或赛车游戏。以下是该插件的一些主要特点和功能: 主要特点: 真实的物理模拟: 提供高度精确的车轮物理,能够模拟真实的轮胎与地面之间的互动。 支持复杂的悬挂系统,可以根据地形变化调整汽车的行驶方式。 引擎、转向、刹车和加速等系统都基于真实物理算法,提供更真实的驾驶体验。 多种驾驶模式: 提供不同的控制方式,适合不同类型的游戏。包括传统的赛车游戏控制、模拟驾驶以及更轻松的街机式驾驶控制。 支持手动和自动变速器,用户可以自由设置。 高级车体控制: 支持不同类型的汽车(如运动型、SUV、卡车等)定制,可以调整每辆车的重量、引擎力量、车轮配置等参数。 车辆能够根据不同的地面情况(如草地、雪地、泥地等)表现出不同的牵引力和滑移效果。 细致的视觉效果: 支持实时反射..

    CrystalDiskInfo9-4-4.exe

    CrystalDiskInfo CrystalDiskInfo9_4_4.exe 监测查看硬盘健康状况 各类硬盘均可 仅适用于Windows

Global site tag (gtag.js) - Google Analytics