垃圾回收的悖论
所谓“成也萧何败萧何”。Java的垃圾回收确实带来了很多好处,为开发带来了便利。但是在一些高性能、高并发的情况下,垃圾回收确成为了制约Java应
用的瓶颈。目前JDK的垃圾回收算法,始终无法解决垃圾回收时的暂停问题,因为这个暂停严重影响了程序的相应时间,造成拥塞或堆积。这也是后续JDK增加
G1算法的一个重要原因。
当然,上面是从技术角度出发解决垃圾回收带来的问题,但是从系统设计方面我们就需要问一下了:
我们需要分配如此大的内存空间给应用吗?
我们是否能够通过有效使用内存而不是通过扩大内存的方式来设计我们的系统呢?
我们的内存中都放了什么
内存中需要放什么呢?个人认为,内存中需要放的是你的应用需要在不久的将来再次用到到的东西
。想想看,如果你在将来不用这些东西,何必放内存呢?放文件、数据库不是更好?这些东西一般包括:
1. 系统运行时业务相关的数据。比如web应用中的session、即时消息的session等。这些数据一般在一个用户访问周期或者一个使用过程中都需要存在。
2. 缓存。缓存就比较多了,你所要快速访问的都可以放这里面。其实上面的业务数据也可以理解为一种缓存。
3. 线程。
因此,我们是不是可以这么认为,如果我们不把业务数据和缓存放在JVM中,或者把他们独立出来,那么Java应用使用时所需的内存将会大大减少,同时垃圾回收时间也会相应减少。
我认为这是可能的。
解决之道
数据库、文件系统
把所有数据都放入数据库或者文件系统,这是一种最为简单的方式。在这种方式下,Java应用的内存基本上等于处理一次峰值并发请求所需的内存。数据的获取都在每次请求时从数据库和文件系统中获取。也可以理解为,一次业务访问以后,所有对象都可以进行回收了。
这是一种内存使用最有效的方式,但是从应用角度来说,这种方式很低效。
内存-硬盘映射
上面的问题是因为我们使用了文件系统带来了低效。但是如果我们不是读写硬盘,而是写内存的话效率将会提高很多。
数据库和文件系统都是实实在在进行了持久化,但是当我们并不需要这样持久化的时候,我们可以做一些变通——把内存当硬盘使。
内存-硬盘映射很好很强大,既用了缓存又对Java应用的内存使用又没有影响。Java应用还是Java应用,他只知道读写的还是文件,但是实际上是内存。
这种方式兼得的Java应用与缓存两方面的好处。memcached的广泛使用也正是这一类的代表。
同一机器部署多个JVM
这也是一种很好的方式,可以分为纵拆和横拆。纵拆可以理解为把Java应用划分为不同模块,各个模块使用一个独立的Java进程。而横拆则是同样功能的应用部署多个JVM。
通过部署多个JVM,可以把每个JVM的内存控制一个垃圾回收可以忍受的范围内即可。但是这相当于进行了分布式的处理,其额外带来的复杂性也是需要评估的。另外,也有支持分布式的这种JVM可以考虑,不要要钱哦:)
程序控制的对象生命周期
这种方式是理想当中的方式,目前的虚拟机还没有,纯属假设。即:考虑由编程方式配置哪些对象在垃圾收集过程中可以直接跳过,减少垃圾回收线程遍历标记的时间。
这种方式相当于在编程的时候告诉虚拟机某些对象你可以在*时间后在进行收集或者由代码标识可以收集了(类似C、C++),在这之前你即便去遍历他也是没有效果的,他肯定是还在被引用的。
这种方式如果JVM可以实现,个人认为将是一个飞跃,Java即有了垃圾回收的优势,又有了C、C++对内存的可控性。
线程分配
Java的阻塞式的线程模型基本上可以抛弃了,目前成熟的NIO框架也比较多了。阻塞式IO带来的问题是线程数量的线性增长,而NIO则可以转换成为常数
线程。因此,对于服务端的应用而言,NIO还是唯一选择。不过,JDK7中为我们带来的AIO是否能让人眼前一亮呢?我们拭目以待。
其他的JDK
本文说的都是Sun的JDK,目前常见的JDK还有JRocket和IBM的JDK。其中JRocket在IO方面比Sun的高很多,不过Sun
JDK6.0以后提高也很大。而且JRocket在垃圾回收方面,也具有优势,其可设置垃圾回收的最大暂停时间也是很吸引人的。不过,系统Sun的G1实
现以后,在这方面会有一个质的飞跃。
相关推荐
JVM调优总结 JVM(Java Virtual Machine)是 Java 语言的运行环境,负责将 Java 字节码转换为机器码并执行。然而,随着 Java 应用程序的复杂度和规模的增加,JVM 的性能变得越来越重要。因此,JVM 调优是非常必要的...
本文档总结了JVM调优的基础知识和一些核心概念,旨在帮助开发者更好地掌握Java程序的性能优化。 首先,文档提到了Java中的数据类型分为基本类型和引用类型。基本类型的变量存储的是原始数据值,而引用类型的变量...
### JVM实战-JVM调优案例分析与MyEclipse性能调优实战 #### 实验背景与目标 在现代软件开发过程中,提升开发效率是至关重要的环节之一。MyEclipse和Eclipse作为主流的集成开发环境(IDE),被广泛应用于Java项目的...
- **跨平台性**:通过JVM(Java虚拟机),使得Java程序可以在任何安装了JVM的平台上运行。 2. **数据类型与基本语法**: - **数据类型**:Java支持多种数据类型,包括基本类型(如int、double、char等)和引用...
- **JVM调优**:探讨常见的JVM性能调优方法,包括具体的参数设置建议。 - **垃圾收集算法**:分析不同的垃圾收集算法(如标记-清除、复制算法等)及其适用场景。 - **垃圾收集器**:介绍常用的垃圾收集器(如Serial ...
5. **JVM调优**: 对Java虚拟机的理解是提高系统性能的关键。需要了解内存模型(堆、栈、方法区等),垃圾收集机制,以及如何通过监控工具(如VisualVM、JConsole)进行性能优化。 6. **分布式**: 分布式系统设计...
对于Java面试,理解垃圾回收机制、内存模型和JVM调优是关键。 接下来是ASP.NET,这是微软提供的用于构建Web应用程序的框架。重点知识包括ASP.NET页面生命周期、控件事件、MVC模式、ADO.NET数据访问、WebAPI、 ...
10. **面试技巧**:"Java八股文"通常指的是面试中常问的问题,如Java内存模型、垃圾收集算法、JVM调优、并发编程难题等。熟悉这些问题并能给出清晰解答,将大大增加面试成功的几率。 在"项目说明.zip"中,可能包含...
12. **性能优化**:JVM调优、代码优化、内存泄漏检测、性能监控工具的使用,都是体现开发者专业性的关键。 在"interviews-master"这个文件夹中,很可能是按照不同的主题或公司分门别类地整理了这些问题和解答。通过...
- 掌握JVM调优,如垃圾回收机制、类加载过程等。 7. **实战经验**: - 参加在线编程竞赛,如LeetCode、HackerRank、Codeforces等,提高解决问题的速度和质量。 - 解决实际项目中的问题,积累实践经验。 8. **...
3. **Tomcat性能调优**:Tomcat的优化包括JVM内存配置、线程池设置、连接器优化等。例如,通过调整-Xms、-Xmx等JVM参数控制内存分配,防止频繁的垃圾回收;设置合理的maxThreads和minSpareThreads以平衡响应速度与...
面试中可能会询问关于内存泄漏、对象生命周期、如何调优JVM参数等方面的问题。 六、设计模式 设计模式是解决常见编程问题的模板,面试中经常通过设计模式来评估候选人的解决问题的能力。常见的设计模式有单例模式、...
Java架构面试专题汇总是针对Java开发人员在求职或者晋升时可能会遇到的一系列技术问题的集锦,涵盖了从基础到高级...同时,结合个人学习笔记,不断反思和总结,将理论知识转化为实际操作能力,进一步提高自己的竞争力。
理解JVM的工作原理,包括类加载机制、内存模型、垃圾回收、调优参数等,能帮助你编写出性能更优的代码,避免内存泄漏和性能瓶颈。 3. 池技术: 对象池、连接池、线程池等技术的掌握是提高系统效率的关键。理解...
同时,深入理解JVM的工作原理、垃圾回收机制以及性能调优技巧,将有助于编写出更高效、稳定的Java应用程序。 总的来说,成为一名优秀的程序员不仅需要扎实的技术基础,还需要不断学习、勇于创新的精神,以及对代码...
除了上述知识点,面试中还可能涉及其他Java后端开发的重点,例如异常处理、JVM内存模型、多线程同步机制、数据库设计与优化、性能调优、设计模式的应用、Spring Boot/Spring Cloud等相关框架的理解和实践经验。...
10. **JVM内存管理**:了解JVM的工作原理对优化性能至关重要。卡塔可能会涉及内存分配、垃圾回收和性能调优。 通过JavaKata,无论是初学者还是经验丰富的开发者,都能持续磨练自己的Java技能,提升编程思维,更好地...