java 虚拟机内存管理_小试Java虚拟机内存管理(Java 8)

最近研究了一下Java虚拟机的内存管理。大体上分为两部分:垃圾回收算法和内存分配。举个不恰当的比喻,好比汽车的变速箱和发动机。当'转速/内存使用'过高时,就会触发'换挡/垃圾回收'。

Java虚拟机的内存分配,大体上可分为年轻代(Young Generation),老年代(Tenured Generation)以及元空间(Metaspace)。其中,新生代又分为Eden(伊甸园),S0和S1(Survivor,幸存者乐园)。(参考《Java程序员修炼之道》及VisualVM)

注:Java 8取消了原来的永久代(PermGen),改为元空间(Metaspace)了。

对应于Java虚拟机的参数设置:

-Xmn的大小 = Eden + S0 + S1

-Xmx的大小 = Eden + S0 + S1 + Old

-XX:SurvivorRatio用来分配Eden和S0,S1的比例

-XX:MaxMetaspaceSize表示Metaspace的最大值(-XX:MaxPermSize在Java 8中已经没用了)

所以Xmn的大小不能超过Xmx,而且最好也不要相等,否则Old空间就变成0了。有些书上说SurvivorRatio的默认值为8:1:1,但是目测Java 8里面的默认值为1:1:1

通过VisualVM可以很直观地观察上面的改动。

f6c8d249e69cd4bf8c2eba8ae2154bdb.png

以观察Eclipse的启动时间为例,需要不断地修改Eclipse的配置文件,并重启Eclipse,操作系统都快被我玩坏了。不过目前VisualVM也有Bug,Metaspace的最大值好像一直是1G左右,最终我把MaxMetaspaceSize改为20m,Eclipse启动出错,说明这个参数是起作用的,从而证明了VisualVM存在Bug。

!SESSION 2015-04-07 20:49:06.963 -----------------------------------------------

eclipse.buildId=4.3.2.M20140221-1700

java.version=1.8.0_25

java.vendor=Oracle Corporation

BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US

Framework arguments: -product org.eclipse.epp.package.standard.product

Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.standard.product

This is a continuation of log file D:\workspace\.metadata\.bak_0.log

Created Time: 2015-04-07 20:49:40.681

!ENTRY org.eclipse.ui 4 0 2015-04-07 20:49:40.697

!MESSAGE Unhandled event loop exception

!STACK 0

org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.OutOfMemoryError: Metaspace)

at org.eclipse.swt.SWT.error(SWT.java:4397)

at org.eclipse.swt.SWT.error(SWT.java:4312)

at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:138)

at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4145)

at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3762)

at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)

at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)

at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)

at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:140)

at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:611)

at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)

at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)

at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)

at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)

at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)

at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)

at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)

at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)

at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)

at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)

at org.eclipse.equinox.launcher.Main.run(Main.java:1450)

Caused by: java.lang.OutOfMemoryError: Metaspace

其实我本来是想调优的,但是Windows 7 64位环境上,无论怎么调整参数,最后的启动时间都是6、7秒的样子,所以最后只能变成调"劣"了。(下图为《深入理解Java虚拟机》中测量启动时间的Eclipse插件)

ddf03517779c82214050c1dea4aa8e7e.png

结论:

Java虚拟机的内存管理没有想象中那么复杂,如果结合VisualVM这种工具来学习,能起到事半功倍的效果。

Java内存空间有时还是挺浪费的,尤其是默认情况下,SurvivorRatio比例为1:1:1的情况下,大概有三分之一的空间一直为空。

关于JVM内存参数的设定还是很有用的,尤其想搞清楚一些问题,希望尽快重现的时候,可以按需求修改空间大小,达到快速把事情搞砸的目的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值