JVM内存和JVM调优(十)--总结

垃圾回收的悖论

所谓“成也萧何败萧何”。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实现以后,在这方面会有一个质的飞跃。

--摘自:https://www.iteye.com/blog/pengjiaheng-558619

原文地址:https://www.cnblogs.com/gllegolas/p/11995300.html

时间: 2024-10-22 07:53:18

JVM内存和JVM调优(十)--总结的相关文章

jvm内存溢出性能调优

常用工具及命令 jps jstat Top jstack jmap mat工具 top -Hp pid可以查看某个进程的线程信息 -H 显示线程信息,-p指定pid jps:可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称及进程pid 如:jps -l pid Jstack命令 jstack是java虚拟机自带的一种堆栈跟踪工具.用于生成java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,

JVM原理讲解和调优

一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码.而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译.Java语言使用Java虚拟机屏蔽了与具体平台相关的信息

深入理解JVM虚拟机10:JVM常用参数以及调优实践

微信公众号[Java技术江湖]一位阿里 Java 工程师的技术小站.作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux.网络.多线程,偶尔讲点Docker.ELK,同时也分享技术干货和学习经验,致力于Java全栈开发!(关注公众号后回复”Java“即可领取 Java基础.进阶.项目和架构师等免费学习资料,更有数据库.分布式.微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南.Java程序员面试指

1.java应用jvm原理及参数调优

什么是jvm? 虚拟机 ,字节码,平台无关 jvm是按照运行时数据的存储结构来划分内存结构的,jvm在运维java程序时,将它们划分成几种不同格式的数据,分别存储在不同的区域,这些数据统一称为运行时数据.运行时数据包括java程序本身的数据信息和jvm运行java需要的额外数据信息. jvm堆配置参数 1  -Xms 初始堆大小 默认物理内存的1/641(<1g) 2  -Xms 最大堆大小 默认物理内存的1/4(<1GB),实际中建议不大于4G. 3 一般建议设置 -Xms= -Xmx 好处

Android内存分析和调优(上)

Android内存分析和调优(上) Android内存分析工具(四):adb命令

Jvm原理剖析与调优之内存结构

一些不得不说的概念 JVM JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一个存储方法域. JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行.是运行java应用最底层部分. JDK(Java Development kit) 整个Java的核心,包括了Java运行环境(

Eclipse 中设置JVM 内存及JVM监控调优

当我们在IDE控制台发现: 说明我们给jvm的持久代设置的值太小,此时你需要打开eclispe 中window->preferences->Java->Installed JRE ,点击右侧的Edit 按钮,在编辑界面中的 "Default VM Arguments "选项中,将-XX:PermSize及  -XX:MaxPermSize的值加大. 如果你懂jvm性能调优的话,从jstat监控中可以得知其中的关系.以下为实际演示操作: 1,按照如下图步骤将-XX:Pe

JVM原理和性能调优

JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境. 1.创建JVM装载环境和配置 2.装载JVM.dll 3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例 4.调用JNIEnv实例装载并处理class类. 在我们运行和调试Java程序的时候,经常会提到一个JVM的概念.JVM是Java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间. 首先来说

JVM堆设置及调优

1.JVM堆设置 -Xmx3550m 设置JVM最大堆内存 为3550M. -Xms3550m 设置JVM初始堆内存 为3550M.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存. -Xss128k 设置每个线程的栈大小.JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K.应当根据应用的线程所需内存大小进行调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右. -Xm

JVM性能分析和调优方向

1)合理配置参数 jvm内存=堆内存+非堆内存 堆内存=新生代+年老代 新生代=1个Eden区+2个survivo区 非堆内存=持久代+代码缓存 -server:服务器模式,该参数放置在配置项的首位置 -Xms:堆的初始大小,单位MB 配置-Xms与-Xmx一致,为可用内存的80% -XmX:堆的最大大小,单位MB -Xmn:新生代的初始大小,单位MB 为堆大小的3/8 当业务中有数据量很大的文件需要导出时,需要调整以下2个参数的值,可避免出现OOM -XX:PermSize:持久代的初始大小,