Java 程序性能优化《第一章》Java性能调优概述 1.2性能调优的层次

简介:

Java 程序性能优化《第一章》1.2性能调优的层次

为了提升系统性能,开发人员开始从系统各个角度和层次对系统进行优化。除了最常见的代码优化外,在软件架构上、JVM虚拟机层、数据库以及操作系统层面都可以通过各种手段进行优化,从而在整体上提升系统的性能。

1.2.1 设计调优

设计调优处于所有调优手段的上层,它往往需要在软件开发之前进行。在软件开发之处,软件架构师就应该评估系统可能存在的各种潜在问题,并给出合理的设计方案。由于软件设计和架构对整体质量有决定性的影响,所以,设计调优对系统性能的影响也是最大的。如果说,代码优化、JVM优化都是对系统微观层面上 “ 量 ” 的优化,那么设计优化就是对系统在宏观层面上 “ 质 ” 的优化。
设计优化的一大显著特点是,它可以规避某一个组件的性能问题,而非改良该组件的实现。比如,系统中组件A需要等待事件E才能触发的行为。如果组件A通过循环监控不断监测事件E是否发生,其监测行为必然会占用部分系统资源,因此,开发人员必须在监测频率和资源消耗取得平衡。如果监测频率太低,虽然减少的资源的消耗,但是系统实时反应性就会降低。如果进行代码层的调优,就需要优化监测方法的实现以及求得一个最为恰当的频率。
而若将次问题预留在设计层解决,便可以使用事件通知的方式将系统行为进行倒置。如使用第2章中提到的观察者模式,在事件E发生的时刻,有事件E通知组件A,从而触发组件A的行为。这种设计方法弃用了存在性能隐患的循环监控,从根本上解决了这一问题。
从某种角度上来说,设计优化直接决定了系统的整体品质。如果在设计层考虑不周到,留下太多问题隐患,那么这些 “ 质 ” 上的问题,也许无法再通过代码层的优化进行弥补。因此,开发人员必须在软件设计之初,认真仔细考虑软件系统的性能问题。
进行设计优化时,设计人员必须熟悉常用的软件设计方法、设计模式、基本性能组件、和常用优化思想,并将其有机地集成在软件系统中。

ps:一个良好的系统设计可以规避很多潜在的性能问题。因此尽可能的多花些时间在系统设计上,是创建高性能程序的关键。

1.2.2 代码调化

代码调优是在软件开发过程中,或许在软件开发完成后,软件维护过程中进行的对程序代码的改进和优化。代码优化设计诸多编程技巧,需要开发人员熟悉相关语言的API,并在合适的场景中正确的使用相关API或类库。同时,对算法、数据结构的灵活运用,也是代码优化的重要内容。
虽然代码优化是从微观上对性能的进行调整,但是一个 “ 好 ” 的实现和一个 “ 坏 ” 的实现对系统的影响也是非常大的。比如,同样作为List的实现,LinkedList 和 ArrayList 在随机访问上的性能却可以相差几个数量级;又如,同样是文件读写的实现,使用 Stream 方式与 Java NIO 的方式,其性能可能又会相差一个数量级。
因此,虽然与设计优化相比,笔者将代码优化称为在微观层面上的优化,但是它却是对系统性能产生最直接影响的优化方法。

1.2.3 JVM 调优

由于Java 软件总是运行在JVM虚拟机之上,对JVM虚拟机进行优化也能在一定程度上提升Java程序的性能。JVM调优通常可以在软件开发后期进行,如在软件开发完成,或者在软件开发的某一个里程碑阶段。
作为Java 软件的运行平台,JVM的各项参数将会直接影响Java程序的性能。比如,JVM的堆大小、垃圾回收策略等。
要进行JVM层面调优,需要开发人员对JVM的运行原理和基本内存结构有一定了解。如,堆内存的结构、GC的种类等。然后依据应用程序的特点,设置合理的JVM启动参数。

1.2.4 数据库调优

对绝大多数应用系统而言,数据库是必不可少的一部分。Java程序可以使用JDBC方式连接数据库。对数据库的调优可以分为3个部分:
  • 在应用层对SQL语句进行优化。
  • 对数据库进行优化。
  • 对数据库软件进行优化。
在应用层优化数据库访问,涉及大量的编程技巧。比如,当使用JDBC进行查询时,对于大量的拥有相同结构的SQL查询,可以使用PreparedStatement 代替 Statement ,以提高数据库的查询效率;在SELECT语句中,显示指定要查询的列名,避免使用星号 “ * ” 。
在对数据库进行优化时,主要目的是建立一个具有良好表结构的数据库。比如,为了提高多表级联查询效率,可以合理的使用冗余字段;对于大表,可以使用行的水平切割或者类似Oracle分区表的技术;为了提高数据库查询效率,可以建立有效且合理的索引。
对于数据库软件的优化,根据不同的数据库,如 Oracle、MySQL或者SQL Server 都拥有不同的方式。以Oracle 为例,设置合理大小的共享池、缓存缓冲区或者PGA,对Oracle的运行性能都有很大的影响。
鉴于本书的讨论范围,数据库优化将不作为本书的阐述重点。

1.2.5 操作系统优化

作为软件运行的基础平台,操作系统的性能对应用系统也有较大的影响。不同类型的操作系统,调优手段和参数可能会有所不同。比如,在主流的UNIX系统中,共享内存段、信号量、共享内存最大值(shmmax)、内存共享最小值(shmmin)等都是可以进行优化的系统资源。此外,如最大文件句柄数、虚拟内存大小、磁盘的块大小等参数都可能对软件的性能产生影响。图1.5展示了在Windows平台上,配置虚拟内存的界面。

图 1.5 Windows 下设置虚拟内存
ps:操作系统的性能调优不在本书的讨论范围内,有兴趣的读者可以参考相关书籍。
相关文章
|
2月前
|
XML Java 数据库连接
性能提升秘籍:如何高效使用Java连接池管理数据库连接
在Java应用中,数据库连接管理至关重要。随着访问量增加,频繁创建和关闭连接会影响性能。为此,Java连接池技术应运而生,如HikariCP。本文通过代码示例介绍如何引入HikariCP依赖、配置连接池参数及使用连接池高效管理数据库连接,提升系统性能。
69 5
|
2月前
|
Java 数据库连接 数据库
优化之路:Java连接池技术助力数据库性能飞跃
在Java应用开发中,数据库操作常成为性能瓶颈。频繁的数据库连接建立和断开增加了系统开销,导致性能下降。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接,显著减少连接开销,提升系统性能。文章详细介绍了连接池的优势、选择标准、使用方法及优化策略,帮助开发者实现数据库性能的飞跃。
36 4
|
2月前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
51 1
|
3月前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
47 2
|
1天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
31 17
|
12天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
14天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
14天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
14天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
39 3
|
14天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
97 2