程序在开发电脑上能跑,客户机器上就崩溃,那是你还没意识到是它?

news2024/9/21 4:40:12

程序开发之谜:为何在开发电脑上一切正常,一到客户机器就崩溃?


1. 引言:

在软件开发的世界里,没有什么比看到自己精心编写的程序在自己的开发环境中完美运行,却在客户机器上突然崩溃更让人抓狂的事情了。这种现象看似诡异,实则背后往往隐藏着一系列潜在的原因,从硬件差异到软件冲突,甚至是系统设置的不同。今天,我们将揭开这个谜团,探讨如何使用Windows资源监视器来诊断并解决此类问题。

2. 莫慌,这个问题具有普遍性

每当在软件开发遇到这种情况时,通常会经历三个阶段:第一阶段是困惑,第二阶段是调查,第三阶段是解决问题。困惑源于预期与现实之间的巨大落差;调查则需要开发者转变角色,从程序员变成侦探;而解决问题,则是对开发者技能和耐心的双重考验。

3 .使用Windows资源监视器进行诊断

Windows资源监视器是Windows系统自带的一个强大工具,它提供了关于CPU、内存、磁盘和网络使用情况的实时数据。以下是使用资源监视器进行诊断的步骤:

步骤0:编写一个WPF程序

编码文件 MainWindow.xaml

<Window x:Class="WPFSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock HorizontalAlignment="Center" Text="Hello, WPF!" FontSize="32" Margin="0,20,0,20" />
            <Label x:Name="cpuTimeLabel" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="32" Margin="0,20,0,20"/>
            <Button HorizontalAlignment="Center" x:Name="myButton" Click="myButton_Click" Margin="0,0,0,20">Click Me</Button>
            <RichTextBox Name="consoleTextBox" Height="250"></RichTextBox>
        </StackPanel>
        
    </Grid>
</Window>

编码文件 MainWindow.xaml.cs

using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using System.Windows.Threading;

namespace WPFSample
{
    public partial class MainWindow : Window
    {
        private Process _currentProcess;
        private DispatcherTimer _timer;

        private const int Port = 8888;
        private TcpListener _listener;
        private TcpClient _ServerTcpClient;
        private TcpClient _ClientTcpClient;

        public MainWindow()
        {
            InitializeComponent();
            // 获取当前进程
            _currentProcess = Process.GetCurrentProcess();

            // 创建一个每秒钟触发一次的定时器
            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMicroseconds(100);
            _timer.Tick += Timer_Tick;
            _timer.Start();
        }

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            (sender as System.Windows.Controls.Button).Content = "Clicked!";
            StartServer();
            StartClient();
        }
        private void Timer_Tick(object sender, EventArgs e)
        {
            UpdateCPUTime();
        }
        private void UpdateCPUTime()
        {
            TimeSpan cpuTime = _currentProcess.TotalProcessorTime;
            cpuTimeLabel.Content = $"CPU 执行时间: {cpuTime}";
        }
        
        private async void StartServer()
        {
            try
            {
                _listener = new TcpListener(IPAddress.Any, Port);
                _listener.Start();
                AppendToConsole("等待客户端连接...");
                _ServerTcpClient = await _listener.AcceptTcpClientAsync();
                AppendToConsole("客户端已连接。");
                await ReceiveMessages();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private async Task ReceiveMessages()
        {
            try
            {
                var stream = _ServerTcpClient.GetStream();
                while (true)
                {
                    byte[] buffer = new byte[1024];
                    int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    string receivedMessage = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    AppendToConsole($"接收到消息: {receivedMessage}");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"接收消息时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private async void StartClient()
        {
            try
            {
                _ClientTcpClient = new TcpClient();
                await _ClientTcpClient.ConnectAsync("127.0.0.1", Port);
                AppendToConsole("已连接到服务器。");
                await SendMessage("Hello from client!");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"连接或发送消息时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void AppendToConsole(string message)
        {
            Dispatcher.BeginInvoke(() =>
            {
                // 在界面上追加消息到文本框
                consoleTextBox.AppendText($"{message}\n");
                consoleTextBox.ScrollToEnd();
            });
        }

        private async Task SendMessage(string message)
        {
            try
            {
                await Task.Run(async () => {
                    while (true)
                    {

                        // 获取网络流
                        var stream = _ClientTcpClient.GetStream();

                        // 发送消息
                        byte[] buffer = Encoding.UTF8.GetBytes(message);
                        await stream.WriteAsync(buffer, 0, buffer.Length);

                        // 显示发送的消息
                        AppendToConsole($"发送消息: {message}");
                        Thread.Sleep(1000);
                    }
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送消息时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
    }
}

执行结果
在这里插入图片描述

步骤1:启动资源监视器

  • 快速访问方法:按下Win + R组合键,输入resmon,然后按Enter键。
  • 或者,在任务管理器中,选择“性能”标签页,点击右下角的“资源监视器”。
    在这里插入图片描述
    选择WpfSample.exe程序
    在这里插入图片描述

步骤2:观察CPU使用情况

CPU选项卡
显示进程、服务、关联句柄和模块。帮助识别CPU使用率高峰和消耗大量CPU时间的进程。在“CPU”标签页,你可以看到所有正在运行的进程以及它们的CPU使用率。注意观察哪些进程在软件崩溃前后的使用率显著上升。
在这里插入图片描述

步骤3:检查内存使用

内存选项卡
显示物理和虚拟内存使用情况,提供有关已提交内存、待机内存和空闲内存的详细信息。切换到“内存”标签页,这里显示了每个进程的内存使用量。如果内存使用量接近或超过了可用内存,这可能是导致崩溃的原因之一。
在这里插入图片描述

步骤4:分析磁盘I/O

磁盘选项卡
提供磁盘活动、磁盘使用情况、存储卷和文件操作的信息。
“磁盘”标签页提供了磁盘活动的实时信息。检查是否有大量的磁盘读写操作正在进行,尤其是当你的软件涉及到数据库或文件操作时。
在这里插入图片描述

步骤5:监控网络流量

网络选项卡
监控网络活动、TCP连接、侦听端口和网络相关进程。
如果软件依赖于网络连接,那么“网络”标签页就非常重要。在这里,你可以看到哪些进程正在消耗网络带宽,以及它们的上传和下载速率。
在这里插入图片描述

4. 收集证据与分析

在客户机器上运行资源监视器时,要求客户在软件崩溃前后进行截图或录屏,以捕获关键数据。同时,使用性能监视器创建数据收集器集,以收集更长时间范围内的性能数据。

使用资源监视器诊断问题

  1. 分析CPU使用情况

    • 识别消耗高CPU资源的进程。
    • 确定程序执行期间是否有任何CPU峰值。
    • 检查是否有任何进程或服务可能干扰程序。
  2. 监控内存使用情况

    • 分析应用程序的内存消耗。
    • 检测可能导致性能下降的内存泄漏或过度内存使用。
    • 比较开发机器和客户机器之间的内存使用模式。
  3. 检查磁盘活动

    • 跟踪应用程序的磁盘I/O操作。
    • 识别由于磁盘读/写操作导致的瓶颈。
    • 比较不同环境中的磁盘使用情况,发现差异。
  4. 检查网络活动

    • 监控应用程序的网络连接和数据传输速率。
    • 识别可能影响应用程序性能的网络相关问题。
    • 验证应用程序是否正确与外部服务器或服务通信。

特别说明

在这里,我们可以看到,当前程序运行时,所依赖的动态库。这些动态库基本上可以划分为几类:

1、由我们的项目引用或者生成的。

在这里插入图片描述
程序运行过程中关联模块部分,由我们自己独立开发命名的模块。

2、dotnet运行环境的动态库。

在这里插入图片描述
这里可以知道,需要安装.NET Desktop Runtime 8.0.7和.NET Runtime 8.0.7。我们这里没有使用到ASP.NET Core Runtime 8.0.7,所以不需要安装这个。

3、VC++环境

在这里插入图片描述
从这里,可以知道,我们的程序需要安装VC++ runtime 14.40.33810.0版本的运行环境,

4、系统运行环境的动态库。

在这里插入图片描述
兼容windows sdk 10.0.2262.3733版本。

5. 其他库

在这里插入图片描述
可能会对程序的运行环境产生一定的影响。

5. 解决问题

根据收集到的信息,你可以开始分析问题。常见的原因包括但不限于:

  • 资源争用:其他高负载进程导致资源不足。
  • 驱动程序兼容性:特定的硬件驱动可能与软件不兼容。
  • 系统设置差异:不同的系统配置或安全设置可能导致问题。
  • 软件冲突:与其他正在运行的应用程序或服务发生冲突。

针对上述每一个可能的原因,都有相应的解决方案,比如优化代码、更新驱动、调整系统设置或修改防火墙规则。

6. 总结

当你面对程序在开发电脑上运行无误,但在客户机器上崩溃的情况时,不要惊慌。通过使用Windows资源监视器,你可以收集到宝贵的线索,帮助你像侦探一样追踪问题的根源。记住,每一次挑战都是成长的机会,让我们一起成为更好的问题解决者吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1965953.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

专业145+总415+成电电子科技大学858考研信号与系统经验电子信息与通信工程,通信抗干扰,资源与环境,航空航天,物理学院,考研真题,大纲,参考书。

暑期相对比较轻松&#xff0c;回顾一下自己的考&#xff0c;总结一些经验&#xff0c;希望对大家有所借鉴&#xff0c;电子科技大学专业课858信号与系统145&#xff0c;总分415&#xff0c;顺利上岸成电。专业课&#xff1a;858信号与系统 资料选择&#xff1a;真题&#xff0…

深度学习实战笔记7kaggle比赛:图像分类

import collections import math import os import shutil import pandas as pd from mxnet import gluon, init, npx from mxnet.gluon import nn from d2l import mxnet as d2lnpx.set_np() 获取并组织数据集 比赛数据集分为训练集和测试集&#xff0c;其中训练集包含50000…

光大远通学生宿舍智能电表如何安装

光大远通学生智能电表需要遵循一系列步骤&#xff0c;‌确保安全、‌正确地完成安装过程。‌ 首先&#xff0c;‌安装智能电表的前期准备工作包括确认电源断开、‌检查接线图纸、‌准备必要的工具等。‌在接线过程中&#xff0c;‌需要特别注意接地连接、‌电源接线、‌负载连…

【空间向量】

框架 空间代数空间直角坐标系向量的概念向量的运算向量间的关系空间平面与直线空间平面两平面的位置关系空间直线的方程两直线的位置关系直线与平面的位置关系空间曲面与曲线球面柱面旋转曲面二次曲面空间曲面在坐标面上的投影 解读 1【空间两点之间的距离】根号下各个位置差的…

Java:IO(File、RandomAccessFile、字节流和字符流、其他流)

1&#xff0c;操作文件类&#xff08;File&#xff09; 1.1&#xff0c;File类的基本介绍 在整个io包中&#xff0c;唯一与文件本身相关的类就是File类。使用File类可以进行创建或删除文件等常用操作&#xff0c;如果要使用一个File类&#xff0c;则必须向File类的构造方法中传…

数学建模--聚类分析

目录 聚类分析的基本概念 常用的聚类算法 K-Means 层次聚类 DBSCAN 高斯混合模型&#xff08;GMM&#xff09; 常用的数学公式和方法&#xff1a; 应用实例 结论 数学建模中的聚类分析在市场细分中的具体应用案例是什么&#xff1f; 层次聚类算法与K-Means算法在处理…

Kafka 为什么这么快的七大秘诀,涨知识了

我们都知道 Kafka 是基于磁盘进行存储的&#xff0c;但 Kafka 官方又称其具有高性能、高吞吐、低延时的特点&#xff0c;其吞吐量动辄几十上百万。 在座的靓仔和靓女们是不是有点困惑了&#xff0c;一般认为在磁盘上读写数据是会降低性能的&#xff0c;因为寻址会比较消耗时间。…

unity2D游戏开发18导出游戏

点击File|build Settings 设置安装环境后&#xff0c;点击Build 选中文件夹 结果 运行 设置退出操作 在RPGGameManager类中加入代码 private void Update(){if (Input.GetKey(KeyCode.Escape)) { Application.Quit();}}

Android 10.0 framework默认沉浸式导航栏功能实现

1. 前言 在10.0的系统rom定制化开发中,在实现导航栏的某些定制化开发中,在某些产品需要实现沉浸式导航栏,就是需要app 能全屏显示同样也能显示导航栏,接下来就来分析下相关的功能实现 如图: 2.framework默认沉浸式导航栏功能实现的核心类 frameworks\base\core\java\andro…

idea恢复git未提交代码

背景&#xff1a;因拉取代码&#xff0c;本地冲突&#xff0c;误操作回滚了&#xff0c;本地未提交代码丢失。 操作步骤&#xff1a; git --> Uncommitted Changes --> Show Shelf 在下方会弹出一个git对话框&#xff0c;右键选择要恢复的代码&#xff0c;选择Unshelve…

使用ssh进行远程登录android 手机-非root

之前使用termux直接在android手机上面敲命令实在是太累了&#xff0c;android的键盘各种的不好用&#xff0c;就想着使用ssh的远程的方式操作&#xff0c; 后面发现了现在的这个方法&#xff0c;非常的有效&#xff0c;提高了不少的办事效率 可以参照下面的步骤进行操作 打开…

Java:数组方法,引用传递,变量类型,Lambda表达式

1&#xff0c;数组定义及使用 1.1&#xff0c;定义数组 Java语言是典型的静态语言&#xff0c;因此Java数组是静态的&#xff0c;即当数组被初始化之后&#xff0c;该数组所占的内存空间、数组长度都是不可变的。Java程序中的数组必须经过初始化才可使用。所谓初始化&#xff…

基于RAG的企业级代码生成系统:从数据清洗到工程化实现

目录 引言数据收集与清洗数据标准化知识图谱构建RAG系统实现代码生成模型训练工程化实现系统评估与优化结论 1. 引言 在现代软件开发中&#xff0c;利用大型语言模型(LLM)生成代码已成为提高开发效率的重要手段。然而&#xff0c;对于企业来说&#xff0c;如何让这些模型了解…

PHP转Go系列 | Carbon 时间处理工具的使用姿势

大家好&#xff0c;我是码农先森。 在日常的开发过程中经常会遇到对时间的处理&#xff0c;比如将时间戳进行格式化、获取昨天或上周或上个月的时间、基于当前时间进行加减等场景的使用。在 PHP 语言中有一个针对时间处理的原生函数 strtotime&#xff0c;大家都知道这个函数只…

细说MCU的DAC输出含谐波的正弦波形信号的方法

目录 一、参考硬件 二、 建立新工程 三、代码修改 1.用MATLAB生成含谐波的波形数据 2. 修改代码PV 四、查看结果 一、参考硬件 本项目依赖的软件和硬件工程参考本文作者写的文章&#xff1a;细说MCU的DAC1和DAC2各自输出一通道模拟信号的方法-CSDN博客 https://wenchm.b…

苹果AI版iOS首日火爆:聊天秒变高情商,大模型成最强嘴替

苹果公司最近推出了其人工智能技术Apple Intelligence&#xff0c;并在iOS 18.1 Beta版中首次亮相&#xff0c;这标志着苹果正式迈入了AI时代。Apple Intelligence深度集成于iOS、iPadOS和macOS系统中&#xff0c;提供了包括写作润笔、通话摘要、内容总结、图像生成等一系列AI功…

移动硬盘传输中断后无法识别的数据救援指南

一、问题解析&#xff1a;移动硬盘传输中断的困境 在日常使用中&#xff0c;移动硬盘作为我们存储和传输大量数据的重要工具&#xff0c;其稳定性和可靠性直接关系到数据的安全。然而&#xff0c;当在数据传输过程中突然遭遇中断&#xff0c;随后发现移动硬盘无法被电脑识别时…

【OceanBase DBA早下班系列】—— obdiag 收集的OB火焰图/扁鹊图解读

1. 前言 上一篇文章讲解了一下obdiag 怎么快速的收集火焰图&#xff0c;那么问题来了&#xff0c;火焰图收集了咋看呢&#xff1f;今天就讲讲。 2. obdiag 一键收集火焰图和扁鹊图原理 其实obdiag收集信息是依赖于远端ob节点上的perf工具&#xff0c;所以务必要在ob节点上安装…

Vue3选择框选择不同的值输入框刷新变化

场景&#xff1a;新增的时候根据选择框的不同来改变输入信息 例如&#xff1a; 实现方式&#xff1a;这个输入框我做的是业务字典实际的值是0和1&#xff0c;在点击选择框的时候用v-if判断选择的值是1还是0&#xff0c;如果是0则是一个输入信息&#xff0c;如果是1则又是另一个…

【面试】前端开发中的“八股文”:助力还是阻力?

引言 在程序员面试中&#xff0c;“八股文”已经成为一个不可或缺的环节。它通常指的是那些面试中频繁出现的、有固定答案的问题&#xff0c;涉及计算机科学的基础知识、编程语言的特性、以及一些常见的设计模式和算法。然而&#xff0c;围绕“八股文”的争议从未停歇。一方面…