`

分布式java应用学习笔记三

阅读更多

深入理解JVM

 

 

classLoader加载.class完成后,有两种执行方式:

解析执行

编译机器码执行:clientserver两种模式

 

Java代码执行机制

编译为class文件

Java源码编译机制

 

A分析和输入的符号表(parseandenter)

Pase词法和说法分析

Enter符号输入到符号表

B处理注解(annotationprocessing)

C语义分析和生成class文件(analyseandgenerate)

 

类加载机制:

装载(load)全限定名+类加载器

链接(link)

初始化(initialize):

调用了new

反射调用类中的方法

子类调用了初始化

Jvm启动过程中指定的初始化类

 

 

类加载器有四种:

BootstrapclassLoader

ExtensionClassLoader加载扩展功能的一些jar

SystemClassLoader加载启动参数中指定的classPath中的jar包和目录

User-DefinedClassLoader(用户自定义类加载器)

 

classLoad提供的几个关键方法

 

loadClass()加载指定类名的方法

查找顺序为:ClassLoader先从已加载的类中--------->parentclassLoad

------------>systemClassLoad---------->最后覆盖findClass来作

特殊处理

findLoadedClass是从当前classLoader实例对象的缓存中查询已加载的类,

调用的是本方法

findClass此方法直接抛出classNotFoundException

 

findSystemClasssystemclassLoader如果未找到继续从bootstrap

classLoader中寻找,未找到返回空

defineClass将二进制字节码转换为字节对象

 

resolveClass完成class对象的链接,如果链接过则直接返回

 

 

 

类加载过程中常抛出的异常

classNotFoundException未找到类文件

noClassDefFoundError加载类中引用的另外的类不存在

linkageError在用户自定义加载器中容易出现,此类已经在classloader中加载过

了,重复加载会出此异常

classCastException类型转换异常

 

 

 

 

类执行机制

字节码解释执行

执行方法的指令:

Invokestatic调用静态方法

Invokevirtual调用对象实例的方法

Invokeinterface调用接口

Invokespecial调用private方法和编译原码后生成的init方法

 

Javac编译代码

Javap-c查看字节码

SunJDK基于栈的体系结构来执行字节码

示例代码如下:

 

Java代码

publicclassDemo{

publicstaticvoidfoo(){

inta=1;

intb=2;

intc=(a+b)*5;

}

 

}

 

 

//字节码如下

publiccn.yue.distributed.esb_soa.Demo();

Code:

0:aload_0

1:invokespecial#1;//Methodjava/lang/Object."<init>":()V

4:return

 

publicstaticvoidfoo();

Code:

0:iconst_1//将类型为int,值为1的常量放入操作数栈

1:istore_0//将操作数栈中的栈顶的值弹出放入局部变量区

 

2:iconst_2//同上

3:istore_1

 

4:iload_0//装载局部变量区中第一个值到操作数栈

5:iload_1//同上装载第二个操作数

6:iadd//执行int类型的add指令并将计算出的结果放入操作数栈

7:iconst_5//将类型为int,值为1的常量放入操作数栈

8:imul//执行int类型的mul方法,将计算出的结果放入操作数栈

9:istore_2//将操作数栈中弹出放入局部变量

10:return//返回

 

}

指令解释执行(冯诺一曼体系中的FDX循环方式)

获取一条指令,解码分派,然后执行

实现FDX循环时有

switch-threading

示例代码:

While(true){

Intcode=fetchNextCode();

Switch(){

CaseIADD:

//dosomething

Case...:

//dosomething

}

 

}

Tooken-threading

示例代码如下;

IADD:{

//doadd;

fetchNextCode();

Dispatch();

}

Iconst_0:{

Push{0};

fetchNextCode();

Dispatch();

}

 

Dircet-threading

Subroutime-threading

Inline-threading

 

栈顶缓存

位于操作数栈顶的值放往寄予存器

 

部分栈帧共存

一个方法调用另一个方法,传到另一个方法的参数已存放在操作数栈的数据

SunJDK作了一个优化,就是当调用方法时,后一方法可将前一方法的操作数栈

作为当前方法的局部变量

 

编译执行

为提升代码的执行性能,JDK提供将字节码编译为机器码的支持,编译在运行时执行

通常为JIT编译器

提供的两种模式为:

clientcompiler

 

JDK1.6以后采用的是线性扫描寄存器分配算法

其他方法的优化:

方法内联

示例代码如下

Publicclassdemo1(){

....

demo2();

....

}

Publicclassdemo2(){

 

}

 

//如果编译后demo2的字节数小于35个字节

会用类以于以下的结梦

Publicclassdemo1(){

//demo2

Publicclassdemo2(){

 

}

 

}

 

 

可以在JDK的启动参数上加-XX:+PrintlnLining

 

去虚拟化

在装载class文件后,如果类中的方法只提供一个实现类。对于调用了此方法的代码,也可以进行方法内联

 

冗余削除

在编译时,根据运行时情况进行代码折叠或削除

privatestaticfinalLoglog=LogFactory.getLog("");

privatestaticfinalbooleanisDebug=log.isDebugEnable();

publicvoidexecute(){

if(isDebug){

//dosth

}

//dosomething

}

如果isDebugEnabled返回的为false

那么以上方法就变为:

publicvoidexecute(){

//dosomething

}

 

Servercompiler图着色寄存器算法(逃逸分析是进行优化的基础)

标量替换

栈上分配

同步消除

 

 

 

 

 

反射执行

 

Classclazz=Class.forName("类名");

Methodmethod=clazz.getMethod("方法名",null);

Objectobject=clazz.newInstance();

method.invoke(object,null);

 

 

 

Jvm内存管理

 

 

方法区存放了要加载的类的信息最小值为16m,最大值为64m

 

:存储对象实例和数组值,也可以理解为new出来的对象

32位操作系统上最大为2G64位机器上没有限制

 

新生代(newgeneration):大多数新建的对象从新生代分配内存

旧生代(oldgeneration):用于存放新生代中多次垃圾回收仍然存在的对象

 

本地方法栈支持本地方法的执行

Pc寄存器和JVM方法栈每个线程都会创建PC寄存器和JVM方法栈

Pc寄存器占用的或操作系统内存

JVM占用操作系统内存

当空间栈空间不足时,会抛stackOverFlowError

 

内存分配

Java对象占用的内存主要从堆上分配,堆是线程共享的,在分配内存时要进行加锁

为每个新建线程分配一块独立的空间(TLAB)threadlocalallocationbuffer

 

 

内存回收

收集器

引用计数收集器

跟踪收集器

实现方法

复制

 

标记-清除

 

标记-压缩

 

JDK中可用的GC

 

新生代可用GC

 

未看完

 

JVM内存状况查看和分析工具

A输出gc日志

输出到控制台:

在启动参数中:-XX+PrintGC-XX:+PrintDetails-XX:+PrintGCTimeStamps

-XX:+PrintGCApplicationStoppedTime

输出到指定文件:

-verbose:gc-XX:+PtingTenuringDistribution

BGCPortal

CJConsole

DJVisualVM

EJMap

FJStat

GEclipseMemoryAnalyzer

 

 

 

JVM线程资源同步及交互机制

 

线程资源同步机制示例代码如下

inti=0;

 

publicintgetNextId(){

returni++;

}

 

以上代码的执行的步骤为:

首先在mainmemory(java堆中)i分配内存,并存0;

线程启动后,会分配一片workingmemory(操作数栈)

i++执行的步骤为:装载读取进行i+1操作,存储i写入i

 

 

线程交互机制

线程状态分析

查看线程状态

Kill-3[线程id]将线程的相关信息输出到控制台

Jstack可以直接查看线程的运行状况

JConsole工具

threadXMBean

TDA

 

 

 

 

序列化和反序列化

 

性能调优

Cpu消耗分析

 

Linuxcpu用于中断、内核、用户进程的任务处理

上下文切换

每个cpu只能执行一个线程采用抢占式调用

运行队列控制每个cpu核上运行队列为1-3

利用率

可以通过top查看进程中的CPU的消耗状态

 

 

Pidstatsystat中的工具,需先安装SYSTAT

Cpu的消耗主要体现在两个方面上ussy

 

 

文件IO消耗分析

跟踪线程的文件IO的消耗

方法一:

Pidstat-d-t-p[pid]100类似的命令可以查看线程IO的消耗状况

方法二:

Iostat

 

 

 

网络IO消耗分析

Google修改kernel方法对网卡中断不均的问题进行修复,或是用支持MSI-X的网卡来修复

查看网络IO消耗状况

Sar-nFULL12

 

内存消耗分析

通过vmstatsartoppidstat等方式来查看swap和物理内存消耗状况

 

Vmstat和内存相关的信息其中swpd是大小说明物理内存不够用,将数

据放到硬盘上的数据的大小

Sar-r参数可以查看内存消耗状况,可以查询历史状况

以上两者不能分析进程所占用的内存量

Top可以查看所消耗的内存量

Pidstatpidstat-r-p[pid][interval][times]

 

 

 

对物理内存的消耗

实现对物理内存的直接操作

publicstaticvoidmain(String[]args)throwsInterruptedException{

Thread.sleep(20000);

System.out.println("readtocreatebytes,soJVMheepwillbeused");

byte[]bs=newbyte[128*1000*1000];

bs[0]=1;

bs[1]=2;

 

Thread.sleep(10000);

System.out.println("readtoallocate&putdirectbytebuffer,noJVMheepshouldbeused");

 

ByteBufferbyteBuffer=ByteBuffer.allocate(128*1024*1024);

byteBuffer.put(bs);

byteBuffer.flip();

Thread.sleep(10000);

System.out.println("readtogc,JVMheepwillbefreed");

 

bs=null;

System.gc();

Thread.sleep(10000);

System.out.println("readtogetbs,thenJVMheapwillbiused");

byte[]resultbytes=newbyte[128*1000*1000];

byteBuffer.get(resultbytes);

System.out.println("resultbytes[1]is:"+resultbytes[1]);

 

Thread.sleep(10000);

System.out.println("readtogcall");

byteBuffer=null;

resultbytes=null;

System.gc();

 

Thread.sleep(10000);

 

}

 

 

 

程序执行慢原回分析

 

锁竟争激烈

未充分使用硬件资源

数据量增长jprofiler可以查看记录程序的时间消耗

 

 

 

性能调优

可以从硬件操作系统JVM程序

 

JVM调优

代大小的调优

在不采用G1的情况下通常minorGC会快于fullGC

各个代大小的设置决定了minorGCfullGC触发的时机

程序调优

Cpuus高的解决方法

添加thread.sleep(),以释放CPU的执行权

Cpusy高的解决方法

减少线程数

网络IO并发操作,可以采用协程(coroutine)来支撑更高的并发量

实现协程的框架为killim

文件IO消耗严重

异步写文件

批量读写

限流

限制文件大小

网络IO消耗

释放不必要的引用

使用对象缓存池

采用合理的缓存失效算法建立缓存池FIFOLRULFU

分享到:
评论

相关推荐

    Java分布式应用学习笔记01分布式Java应用和SOA

    ### 实现分布式Java应用的挑战与解决方案 尽管Java提供了丰富的库和技术栈来支持分布式应用的开发,但在实际应用中仍面临许多挑战,例如: - **一致性问题**:在分布式系统中保持数据的一致性是一项复杂任务,需要...

    Java【分布式】学习笔记01分布式Java应用

    从给定的文件信息来看,标题和描述都指向了“Java分布式学习笔记01分布式Java应用”,这显然是关于Java在分布式环境下的应用和技术的学习资料。虽然提供的部分内容由于格式问题难以直接解析,但我们可以根据标题、...

    Java分布式应用学习笔记

    Java分布式应用学习笔记 在Java世界中,分布式应用是指由多个独立组件通过网络通信协同工作的系统。这种架构模式常用于构建大规模、高可用性、可扩展的系统。本笔记将深入探讨Java分布式应用的核心概念、技术和实践...

    Java分布式应用学习笔记07线程池应用

    ### Java分布式应用学习笔记07线程池应用 在深入探讨Java分布式应用中线程池的应用之前,我们先来理解一下线程池的基本概念及其在并发编程中的重要性。线程池是Java并发编程的核心技术之一,它通过复用一组预创建的...

    对于\"Java分布式应用学习笔记\"的整理

    分布式系统和SOA的介绍与应用 前言 随着系统规模的扩大,分布式架构的应用变得越来越广泛。...在Java领域,分布式应用的学习和实践是一个非常重要的方向,这对于理解和掌握现代企业级应用架构具有重要意义。

    Java分布式应用学习笔记-谈JVM.doc

    【Java分布式应用学习笔记-谈JVM】 在Java分布式应用中,JVM(Java虚拟机)扮演着至关重要的角色。虽然有些人可能认为分布式系统与JVM的关系并不密切,但事实上,尤其是在大型分布式环境,如云计算服务平台,对Java...

    Java分布式应用学习笔记09JMX-MBean的介绍

    ### Java分布式应用学习笔记09JMX-MBean的介绍 #### MBean概念及作用 MBean,即Managed Bean,是在JMX(Java Management Extensions)框架中用于管理资源的一种特殊Java对象。通过MBean,可以方便地对应用程序进行...

    java分布式应用学习笔记05多线程下的并发同步器.pdf

    本篇笔记将深入探讨Java中的并发同步机制,包括核心概念、工具类以及在实际开发中的应用。 首先,我们要理解什么是线程安全。线程安全是指在多线程环境下,一个方法或类能够正确处理多个线程同时访问的情况,不会...

    Java分布式应用学习笔记06浅谈并发加锁机制分析

    ### Java分布式应用学习笔记06浅谈并发加锁机制分析 #### 1. 前言 在深入探讨Java中的并发加锁机制之前,我们有必要回顾一下多线程环境下的一些基本概念和技术。之前的多线程调度、并发调度以及线程加锁安全等内容...

    Java分布式应用学习笔记05多线程下的并发同步器

    ### Java分布式应用学习笔记05多线程下的并发同步器 #### 1. 前言 在现代软件开发中,特别是在分布式系统和高性能计算领域,有效地管理多线程之间的协同工作至关重要。Java语言提供了丰富的工具和API来帮助开发者...

    Java分布式应用学习笔记08JMX规范与各种监控场景.pdf

    Java Management Extensions (JMX) 是Java平台上的一个标准,它定义了一种管理和监控Java应用程序的...无论是简单的本地程序还是复杂的分布式系统,JMX都是一个强大的工具,帮助我们更好地理解和控制我们的Java应用。

    (完整版)最全的java学习笔记(必看).pdf

    Java学习笔记 Java是一种流行的编程语言,广泛应用于Android应用程序开发、Web应用程序开发、桌面应用程序开发等领域。以下是Java学习笔记的摘要信息: 一、Java技术基础 * 1.1 编程语言:Java是一种面向对象的...

    Java分布式应用学习笔记03JVM对线程的资源同步和交互机制

    ### Java分布式应用学习笔记03:JVM对线程的资源同步和交互机制 在深入探讨Java虚拟机(JVM)如何处理线程间的资源同步与交互机制之前,我们先来明确几个关键概念:线程、多线程、同步、并发以及它们在Java中的实现...

    分布式技术相关知识学习笔记

    【分布式技术相关知识学习笔记】 分布式技术是现代软件开发中的重要组成部分,它涉及多种技术手段,如CORBA、ORB、RPC、RMI以及中间件等,旨在解决大型系统中复杂度、扩展性和高可用性的问题。本笔记将重点讨论EJB...

    [实战]Java分布式高级架构师课程学习笔记.docx

    【Java分布式高级架构师课程学习笔记】 在Java分布式高级架构师的学习过程中,涵盖了多个关键领域的技术,包括数据库的高可用方案、缓存系统、消息中间件以及分布式协调服务。以下是对这些主题的深入探讨: 1. **...

    Java分布式应用学习笔记09JMX-MBean的介绍.doc

    java

Global site tag (gtag.js) - Google Analytics