作为当前更受欢迎和广泛使用的开源操作系统之一,Linux平台下Java虚拟机(JVM)的稳定性和性能始终是不可忽视的问题。JVM为Java程序提供的内存管理系统使Java应用程序的编写和维护变得非常方便,但随着程序复杂度的增加,程序对内存的需求也会不断增加,进而对JVM的内存运行能力提出了更高更复杂的要求。在这里,我们将分享一些如何优化Linux下JVM内存运行的简单技巧。
一、理解JVM内存模型
在实现Java应用程序时,内存管理有以下4个主要部分:堆、方法区、栈和PC寄存器。同时,JVM还有一个内存池用于管理字符串值和其他基本对象。堆是JVM内存空间中的更大区域,被用于存储所有的对象,而一些线程和对象的局部变量则保存在栈中。 PC寄存器用于存储当前执行的指令地址,而方法区用于存储Java类的元信息,比如类名、方法名、字段名称和字节码。 JVM还使用内存池来保存字符串值和其他特殊对象。
二、设置JVM内存参数
JVM内存参数对于应用程序的稳定性和性能的影响非常显著,因此手动设置这些参数是优化Java应用程序性能的一个非常有效的方法。以下是一些必须考虑的参数:
1. Xmx参数:指定JVM更大可用内存,以字节数为单位。我们可以根据 服务器 的硬件配置以及应用程序的实际需求来调整此参数。也就是说,我们需要为每个应用程序定制Xmx的值。
2. Xms参数:指定JVM启动时使用的内存量。通常,我们建议将Xmx和Xms设置为相同的值。
3. PermSize参数:PermSize参数用于设置方法区的初始内存大小。该参数在Java6及更高版本中不再使用,但在Java5及更低版本中仍可使用。
4. MaxPermSize参数:用于定义JVM更大PermSize的大小。该参数在Java6及更高版本中不再使用,但在Java5及更低版本中仍可使用。
5. Xss参数:该参数用于设置每个线程堆栈的大小。同样,我们可以根据应用程序的实际需要来确定此值。
三、避免过度使用GC
在Java应用程序中,垃圾收集器是一个非常重要的机制。当程序需要清理未使用的内存时,垃圾收集器就会开始工作。垃圾收集器会把不再使用的对象从内存中删除,从而使更多的内存可用。不过,频繁的垃圾收导致应用程序的性能下降。因此,我们需要采取措施来优化内存管理,从而减少垃圾收集器的运行次数。
1. 避免创建过多的短寿命对象
短寿命对象是一种生命周期很短的对象,在大多数情况下,短寿命对象会很快被垃圾收集器回收。因此,为了避免垃圾收集器的频繁执行,我们可以尝试减少短寿命对象的创建。
2. 尽可能使用局部变量
如果一个对象只在函数内部使用,我们应该尽量将其定义为局部变量。这样做有两个好处:
a. 减少了垃圾收集器的负担,因为这些对象只会被分配在栈上,而不是堆中。
b. 加快了函数的执行速度,因为局部变量在栈上分配,而栈上的分配操作比堆上的分配操作要快得多。
四、Java 8中的内存改进
Java 8引入了一些新的内存管理特性,如针对G1收集器的JVM堆监控API和堆Dump API。这些新特性可以帮助我们更好地诊断程序内存使用情况,从而更好地优化应用程序的性能。
1. G1收集器是Java 8中新引入的垃圾收集器,它采用了一种不同于标记清除(Mark-Sweep)和标记整理(Mark-Compact)的算法,并针对大内存设置做了一些优化。
2. JVM堆监控API可以让我们实时监控JVM堆的使用情况,以便及时发现和解决内存泄漏等问题。
3. 堆Dump API可以让我们在程序运行时生成堆Dump文件,用于更加详细地分析应用程序的堆使用情况。
五、其他一些小技巧
除了上述技巧外,我们还可以尝试以下一些小技巧来优化JVM的内存使用:
1. 合理地使用缓存
如果某个对象需要频繁地被使用,我们可以尝试使用缓存来提高程序的性能。通过缓存,我们可以减少对象的创建次数,从而降低垃圾收集器的工作量。
2. 尽可能使用原始类型
如果可能,我们应该尽可能使用原始类型而不是对象类型。原始类型在使用内存方面更加高效,因为它们在栈上分配,而不是堆上。这样可以减少垃圾收集的负担,从而提高程序的性能。
3. 优化代码逻辑
我们应该尽可能地优化应用程序的代码逻辑,从而减少内存的使用。在实现一些复杂算法时,我们可以尝试使用一些高效的数据结构和算法来优化程序的性能。同时,我们还可以尝试通过减少类的继承层次以及减少Java反射调用等方式来减少内存的使用。
JVM的内存管理对于应用程序的性能和稳定性至关重要。通过对以上优化技巧的掌握,我们可以更好地管理JVM的内存,并优化我们的Java应用程序的性能。如果你的应用程序日益变得复杂,我们建议你尽早优化内存管理,以确保程序的健康运行。
相关问题拓展阅读:
linux启动脚本的jvm怎么设置
不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择不同的GC策略,调整JVM、GC的参数,可以极大的减少由于GC工作,而导致的程序运行中断方面的问题,进而适当的提高Java程序销正的工作效率。但是调整GC是以个极为复杂的过程,由于各个程序具备不同的特点,如:web和GUI程序就有很大区别(Web可以适当的停顿,但GUI停顿是客户无法接受的),而且由于跑睁谨在各个机器上的配置不同(主要cup个数,内存不同),所以使用的GC种类也会不同(如何选择见GC种类及如何选择)。本文将注重介绍JVM、GC的一些重要参数的设置来提高系统的性能。
GC性能方面的考虑
对于GC的性能主要有2个方面的指标:吞吐量throughput(工作时间不算gc的时悉斗基间占总的时间比)和暂停pause(gc发生时app对外显示的无法响应)。
1. Total Heap
默认情况下,vm会增加/减少heap大小以维持free space在整个vm中占的比例,这个比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。
一般而言,server端的app会有以下规则:
对vm分配尽可能多的memory;
将Xms和Xmx设为一样的值。如果虚拟机启动时设置使用的内存比较小,这个时候又需要初始化很多对象,虚拟机就必须重复地增加内存。

处理器核数增加,内存也跟着增大。
2. The Young Generation
另外一个对于app流畅性运行影响的因素是young generation的大小。young generation越大,minor collection越少;但是在固定heap size情况下,更大的young generation就意味着小的tenured generation,就意味着更多的major collection(major collection会引发minor collection)。
NewRatio反映的是young和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,将这两个值设为一样就固定了young generation的大小(同Xms和Xmx设为一样)。
如果希望,SurvivorRatio也可以优化survivor的大小,不过这对于性能的影响不是很大。SurvivorRatio是eden和survior大小比例。
一般而言,server端的app会有以下规则:
首先决定能分配给vm的更大的heap size,然后设定更佳的young generation的大小;
如果heap size固定后,增加young generation的大小意味着减小tenured generation大小。让tenured generation在任何时候够大,能够容纳所有live的data(留10%-20%的空余)。
经验&&规则
年轻代大小选择
响应时间优先的应用:尽可能设大,直到接近系统的更低响应时间限制(根据实际情况选择).在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象.
吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度.因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用.
避免设置过小.当新生代设置过小时会导致:1.YGC次数更加频繁 2.可能导致YGC对象直接进入旧生代,如果此时旧生代满了,会触发FGC.
年老代大小选择
响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数.如果堆设置小了,可以会造成内存碎 片,高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间.更优化的方案,一般需要参考以下数据获得:
并发垃圾收集信息、持久代并发收集次数、传统GC信息、花在年轻代和年老代回收上的时间比例。
吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象.
关于linux jvm 内存的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
香港服务器首选树叶云,2H2G首月10元开通。树叶云(shuyeidc.com)提供简单好用,价格厚道的香港/美国云服务器和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。
ubuntu怎么用命令打开pycharm?
linux系统如何进行Cache空间的清理及调试
Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches频繁的文件访问会导致系统的Cache使用量大增$ free -mtotal used free shared buffers cachedMem: 3955 3926 28 0 55 3459-/+ buffers/cache: 411 3544Swap: 5726 0 5726free内存减少到几十兆,系统运行缓慢运行sync将dirty的内容写回硬盘$sync通过修改proc系统的drop_caches清理free的cache$echo 3 > /proc/sys/vm/drop_cachesdrop_caches的详细文档如下:Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, caUsing that memory to become free pagecache:* echo 1 > /proc/sys/vm/drop_cachesTo free dentries and inodes:* echo 2 > /proc/sys/vm/drop_cachesTo free pagecache, dentries and inodes:* echo 3 > /proc/sys/vm/drop_cachesAs this is a non-destructive operation, and dirty objects are notfreeable, the user should run sync first in order to make sure allcached objects are tunable was added in 2.6.16.修改/etc/ 添加如636f下选项后就不会内存持续增加_ratio = _background_ratio=_writeback_centisecs=_expire_centisecs=_caches= =_cache_pressure=_memory=_reserve_ratio=32 32 =3上面的设置比较粗暴,使cache的作用基本无法发挥。 需要根据机器的状况进行适当的调节寻找最佳的折衷。
linux 如何动态分配内存
Linux内核运行在X86机器的物理内存管理使用简单平坦内存模型,每个用户进程内存(虚拟内存)地址范围为从0到TASK_SIZE字节,超过此内存的限制不能被用户访问。 用户进程被分为几个逻辑段,成为虚拟内存区域,内核跟踪和管理用户进程的虚拟内存区域提供适当的内存管理和内存保护处理。 do_brk()是一个内核函数,用于间接调用管理进程的内存堆的增加和缩减 (brk),它是一个mmap(2)系统调用的简化版本,只处理匿名映射(如未初始化数据)。 do_brk()改变进程的地址空间。 地址是代表数据段结束的一个指针(事实上是进程的堆区域)。 do_brk()的参数是一个绝对逻辑地址,这个地址代表地址空间新的结尾。 更实际地说,我们在编写用户程序的时候从来就不应该使用这个函数。 使用这个函数的用户程序就不能再使用malloc(),这是一个大问题,因为标注库的许多部分依赖于malloc()。 如果在用户程序中使用do_brk()可能会导致难以发现的程序崩溃。 do_brk(addr, len)函数给从addr到addr+len建立虚拟内存区vm_area_struct(该区的起始地址为addr;结束地址为addr+len),该虚拟内存区作为进程的堆来使用。 malloc将从此区域获取内存空间(虚拟内存), free()将会把malloc()获取的虚拟空间释放掉(归还到该进程的堆的空闲空间中去)
发表评论