Java与CPU浅见

作为一个JAVA程序员我们也应该知道计算机是何如运行的,计算机本身是如何完成工作的。其实我很后悔大二的时候没有好好学习那些计算机底层的知识,把大部分是时间花费在那些花拳绣腿上。

一、CPU的基本单位是线程,我们编写的程序通过进程或者线程请求CPU进行处理,首先CPU会分配处理的时间片,处理的时候将操作数传递给CPU,最后处理的结果输出到‘本地变量’中,这个‘本地变量’及时我们说常说的‘栈’(先进后出)。为了提升性能那些数据将会被Cache到缓存当中,我们知道缓存有一级缓存、二级缓存和三级缓存。容量最大的是三级缓存也就是几十兆。缓存既然与CPU交互最快为什么容量那么小?百度百科的解释是:“由于一级缓存的技术难度和制造成本最高,提高容量所带来的技术难度增加和成本增加非常大,所带来的性能提升却不明显,性价比很低”,而且如果缓存的容量过大,就像内存一样就会涉及到很复杂的算法进行管理。

我们知道JAVA之所以能够实现“一次编写,到处运行”是因为有一个强大的JVM,在程序运行的时候会通过java的虚指令来完成JAVA虚拟机中的数据和对象的一些操作,最后根据不同的OS将这些虚指令翻译成OS真正的指令。

二、现在大多数的计算机都是多核的,就像多个人去处理一项任务一样。那么问题来了,当一个请求来的时候CPU是怎么知道的呢?当发起请求的时候是哪个CPU进行处理?一份数据同时被多个CPU操作,如何通知其他CPU我做了什么?

对于第一个问题我的想法是类似与键盘一样,监听器不断的对键盘进行扫描监听,如果这样CPU会非常的繁忙并且效率不高,这时有了“中断技术”,有了它CPU不用自己去问有没有请求来,而是需要请求的处理的设备发送出一个“请求中断”信号,这时CPU便会放下手头的工作去去处理这个请求。完整的过程是:请求中断→响应中断→关闭中断→保留断点→中断源识别→保护现场→中断服务子程序→恢复现场→中断返回。

第二个问题我的想法是由一个请求处理CPU来控制所有的请求操作,这样的有一些弊端,比如:当请求量很大的时候这个CPU估计会吃不消。那么不同的CPU处理不同的区域,用划分区域的方法。这样也有弊端:不同区域之间可能会互相通信。

三、CPU处理的速度是非常快的,这里就出现了Cache Line,Cache 一行或者多行。举一个例子:如果要遍历一个二维数组 int[][] a=new int[5][10]; 有两种方法进行遍历我们常用的是第一维作为外循环,第二维作为内循环;第二种相反,那么两种方法效率是否一致呢? 我平时也是乱来,不知道其中与CPU读取时有怎样的差距。刚才说的Cache Line是连续读入相邻的内存,JAVA数组中分配内存是先分配第一维,然后再分配第二维子数组,例如:int[2][1]和int[3][1]是位于不同的一个数组上的,所以用Cache Line到Cache到CPU缓存中的时候会连续的读入多个,如果用第二中方法读入,数据在不同的数组中也就是在内存中的区域不同,那么Cache Line就不会发挥出他的作用,最后便会一个一个的读入,变得很慢。

四、当数据以及Cache到缓存中以后,如果多个CPU都需要对这个数据进行处理,怎样保持各个CPU的读写一致性?就有了一个MESI协议(缓存一致性协议)。多个CPU通过总线相互连接,每个CPU除了要处理自己的请求之外还要监听总线上其他CPU的读写操作,通过监听自己的Cache做相应的处理,形成了虚共享。MESI我也不是很清楚,只知道几个基本的规则,1.一个CPU加载内存是专用的;2.当另一个CPU也加载了同一块内存时,那么此时两个CPU持有的信息将处于共享状态。

跟CPU相关的还有并发操作,并发还没认真专学习过,一直觉得自己用不上,其实并发随处可见,只是很多框架都帮我们处理好了。下次再谈并发吧,写的很粗糙,主要还是梳理思路和分享一些重要的东西。

时间: 2024-11-11 09:18:23

Java与CPU浅见的相关文章

Java进程CPU高

Java进程CPU高1-1) 查看$PID进程里面的线程CPU占用状况    top -H -p $PID1-2) 显示线程列表,并按照CPU占用高的线程排序     ps -mp $PID -o THREAD,tid,time | sort -rn2) 找出CPU消耗较多的线程id, 并转换成16进制     printf "%x\n" $TID3) 查询出具体的线程状态     jstack $PID | grep -A 10 0x$TID

Linux下java进程CPU占用率高-分析方法

今天登陆同事的一台gateway 开始以为hive环境登陆不了了,仔细一看看了下是因为机器很卡,我每次等几秒没登陆就ctrl+c了,看了下是有个java进程cpu:340.4%  mem:14.6% 一般解决方法是通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用 1. 通过top命令找到可疑进程PID top 一下 可以看出java进程CPU利用率一直保持100%,稳居不下,找到PID 24138 2. 找出消耗资源最高的线程 top -H -p  29580 

记一次java应用cpu利用率过高调试经历

1,现象 写的一个storm应用,主要是通过mysql的binlog来同步表到hbase.运行一段时间后发现,经常会出现cpu使用率飙升到200%以上,然后各种消息堆积报警等等出现各种问题 2,调研过程 cpu使用率很高,所以首先找到该进程,通过top命令,监控该进程的使用率,然后通过H,查看各个线程的cpu使用率情况,记下cpu使用率高的线程id,然后通过jstack pid,获取各个线程栈,听过top获取的线程id转化成16进制后,发现有问题的线程栈如下: 发现主要问题原来出现在HashMa

jstack命令定位java程序CPU利用率高的代码位置

高手是怎么使用jstack精确找到异常代码的(java程序CPU利用率高的情况) 请jstack神器来帮忙 本文介绍Linux环境下使用jstack定位问题的秘笈s1.[top命令]找到CPU利用率持续比较高的进程,获取[进程号],此处PID为 1289112891 s2.[ps p 12891 -L -o pcpu,pid,tid,time,tname,cmd 命令]找到上述进程中,CPU利用率比较高的[线程号TID](十进制数),此处为 12946ps p 12891 -L -o pcpu,

java获取cpu,内存,磁盘等信息

原文:java获取cpu,内存,磁盘等信息 源代码下载地址:http://www.zuidaima.com/share/1550463331306496.htm package com.zuidaima.util; import java.io.File; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.ArrayList; import java.util.List; imp

java程序CPU消耗分析之找出最耗CPU线程

java程序CPU消耗过高一般有两种情况: 1. us过高,应用占用CPU资源过高,需找出具体占用CPU的线程所执行的代码,分析定位问题原因. 分析步骤如下: (1) 使用top命令找出占用cpu最高的JAVA进程 (2) 找出占用cpu最高的线程  top -Hp 1781 (3) 占CPU最高线程17596换算成16进制对应线程44bc 用命令 printf "%x\n" 17596 (4) 打印占CPU最高JAVA进程1781的堆栈信息 jstack 1781> stack

方法:Linux 下用JAVA获取CPU、内存、磁盘的系统资源信息

CPU使用率: InputStream is = null; InputStreamReader isr = null; BufferedReader brStat = null; StringTokenizer tokenStat = null; // 用来分隔String的应用类 try { System.out.println("Get usage rate of CUP : "); Process process = Runtime.getRuntime().exec(&quo

从Java到CPU指令系列之 - 锁和原子操作是怎么实现的 How Lock and atomic works

给急性格的读者: 请参考<Intel 64 and IA32 Architectures Software Develeloper's Manual>.其中有CMPXCHG指令和LOCK指令前缀.或者AMD等其他厂商的开发指南. 在多线程编程中,对某一资源的同步操作是保证资源状态一致性的关键.这个需要同步的资源可以是单个简单的变量,也可以是多个变量,或者是某些外部资源.对他们同步操作的含义就是同一时间点,最多只能有一个线程在操作这些资源,也就是排他性.并且一系列操作必须一气呵成,中间不允许其他

排查linux下java应用cpu占用过高

用于快速排查Java的CPU性能问题(top us值过高),自动查出运行的Java进程中消耗CPU多的线程,并打印出其线程栈,从而确定导致性能问题的方法调用.目前只支持Linux.原因是Mac.Windows的ps命令不支持列出进程的线程id,更多信息参见#33,欢迎提供解法. PS,如何操作可以参见@bluedavy的<分布式Java应用>的[5.1.1 CPU消耗分析]一节,说得很详细: top命令找出消耗CPU高的Java进程及其线程id: 开启线程显示模式(top -H,或是打开top