1.堆内存溢出示例代码
import java.util.ArrayList;import java.util.List;public class TestHeap { public static void main(String[] args) { Listlist = new ArrayList<>(); while(true) { list.add(new User()); } } }
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.chaoyijuechen.easypoi.TestHeap.main(TestHeap.java:10)
问:这是个小程序,可以快速定位内存溢出的位置,若是大应用中呢?代码上百万行,很难通过代码定位。这时该如何定位呢?
答:通过分析工具定位!
问:如何通过分析工具定位?
答:首先,将内存转储成一个快照,然后通过快照对当前环境进行分析。
问:如何生存快照?
答:通过Java虚拟机的参数设置!
-XX:+HeapDumpOnOutOfMemoryError 将Java堆内存溢出的堆存储快照dump
-vmargs //虚拟机设置
-Xms40m //初始内存
-Xmx256m //最大内存
-Xmn16m //最小内存
-XX:PermSize=128M //非堆内存
-XX:MaxPermSize=256M
最终会生成文件在项目根目录下:java_pid1124.hprof,内容如下: ( java version 1.8.0_181)
4a41 5641 2050 524f 4649 4c45 2031 2e302e31 0000 0000 0800 0001 6951 3126 08010000 0000 0000 0012 0000 7fe8 4b05 81d04352 4c5f 5245 4153 4f4e 0100 0000 00000000 2500 007f e84c 04c2 d073 756e 2f736563 7572 6974 792f 706b 6373 2f43 6f6e7465 6e74 496e 666f 0100 0000 0000 00003100 0000 0103 45aa 4028 4c6a 6176 612f7574 696c 2f53 6574 3c54 453b 3e3b 4c6a6176 612f 6c61 6e67 2f4f 626a 6563 743b2956 0100 0000 0000 0000 1300 0000 01034343 406c 696e 6b4d 6574 686f 6420 01000000 0000 0000 1f00 007f e84a 41ec 106e616d 6541 6e64 5479 7065 4370 496e 666f4f66 6673 6574 0100 0000 0000 0000 1a00007f e84b 84ab 5074 7970 6520 6361 6e277420 6265 206e 756c 6c01 0000 0000 0000001c 0000 0001 0346 8fa0 6973 416c 7068614e 756d 6572 6963 5374 7269 6e67 01000000 0000 0000 3300 0000 0103 437a 00284c6a 6176 612f 6c61 6e67 2f43 6c61 73733c2a 3e3b 4c6a 6176 612f 6c61 6e67 2f436c61 7373 3c2a 3e3b 295a 0100 0000 00000000 5000 0000 0103 45b0 e028 4c6a 6176612f 6c61 6e67 2f53 7472 696e 673b 5b4c6a61 7661 2f6c 616e 672f 5374 7269 6e673b4c 6a61 7661 2f69 6f2f 4669 6c65 3b29 ..........
不同版本的jdk生存的快照文件可能不一样。 ( java version 1.8.0_144)
然后下载Eclipse Memory Analyer分析工具进行分析
【Mac版 Eclipse Memory Analyzer报错问题】MemoryAnalyzer-1.8.1.20180910-macosx.cocoa.x86_64.zip
下载后双击解压:在文件夹窗口的显示名称是mat,命令行中看名称是mat.App。鼠标双击mat,报如下错误错
查看此log文件
!SESSION 2019-03-07 08:40:43.357 -----------------------------------------------eclipse.buildId=unknownjava.version=1.8.0_181java.vendor=Oracle CorporationBootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=zh_CNFramework arguments: -keyring /Users/guchunchao/.eclipse_keyringCommand-line arguments: -os macosx -ws cocoa -arch x86_64 -keyring /Users/guchunchao/.eclipse_keyring!ENTRY org.eclipse.osgi 4 0 2019-03-07 08:40:48.803!MESSAGE Application error!STACK 1java.lang.IllegalStateException: The platform metadata area could not be written: /private/var/folders/37/y__4k3h10q77946z33vk7hqm0000gn/T/AppTranslocation/65F1F51A-AE28-408E-BD87-E0A4EAA7E11E/d/mat.app/Contents/MacOS/workspace/.metadata. By default the platform writes its contentunder the current working directory when the platform is launched. Use the -data parameter tospecify a different content area for the platform. at org.eclipse.core.internal.runtime.DataArea.assertLocationInitialized(DataArea.java:70) at org.eclipse.core.internal.runtime.DataArea.getStateLocation(DataArea.java:138) at org.eclipse.core.internal.preferences.InstancePreferences.getBaseLocation(InstancePreferences.java:44) at org.eclipse.core.internal.preferences.InstancePreferences.initializeChildren(InstancePreferences.java:209) at org.eclipse.core.internal.preferences.InstancePreferences.(InstancePreferences.java:59) at org.eclipse.core.internal.preferences.InstancePreferences.internalCreate(InstancePreferences.java:220) at org.eclipse.core.internal.preferences.EclipsePreferences.create(EclipsePreferences.java:349) at org.eclipse.core.internal.preferences.EclipsePreferences.create(EclipsePreferences.java:337) at org.eclipse.core.internal.preferences.PreferencesService.createNode(PreferencesService.java:393) at org.eclipse.core.internal.preferences.RootPreferences.getChild(RootPreferences.java:60) at org.eclipse.core.internal.preferences.RootPreferences.getNode(RootPreferences.java:95) at org.eclipse.core.internal.preferences.RootPreferences.node(RootPreferences.java:84) at org.eclipse.core.internal.preferences.AbstractScope.getNode(AbstractScope.java:38) at org.eclipse.core.runtime.preferences.InstanceScope.getNode(InstanceScope.java:77) at org.eclipse.ui.preferences.ScopedPreferenceStore.getStorePreferences(ScopedPreferenceStore.java:225) at org.eclipse.ui.preferences.ScopedPreferenceStore. (ScopedPreferenceStore.java:132) at org.eclipse.ui.plugin.AbstractUIPlugin.getPreferenceStore(AbstractUIPlugin.java:287) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:609) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:597) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) at org.eclipse.mat.ui.rcp.Application.start(Application.java:26) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:656) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:592) at org.eclipse.equinox.launcher.Main.run(Main.java:1498)
原因:/private/var/folders/37/y__4k3h10q77946z33vk7hqm0000gn/T/AppTranslocation/65F1F51A-AE28-408E-BD87-E0A4EAA7E11E/d/mat.app/Contents/MacOS/workspace/.metadata文件是只读的。
解决方案:
1、新建/Users/guchunchao/eclipse-analyser-log 目录
2、重新定义log文件所在位置:打开mat.app/Contents/Eclipse/MemoryAnalyzer.ini,填入如下2行数据,位置一定要放在 --launcher.library之前
-startup../Eclipse/plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar-data/Users/guchunchao/eclipse-analyser-log--launcher.library../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.700.v20180518-1200-vmargs-Xmx1024m-Dorg.eclipse.swt.internal.carbon.smallFonts-XstartOnFirstThread
将mat复制到【应用程序】中,这样就可以通过【启动台】点击打开了
图1
图2