1, What is multithreading
2, Creation method of multithreading
3, Why use thread pools
4, What about memory overflow
Oom: OUTOFMEMORY (memory overflow)
Common exceptions in development:
1.StackOverFlowError
Example: there are many methods after recursive call, which explodes the stack space
public class StackOverFlowErrorDemo{ public static void main(){ test(); } private static void test(){ //Recursive call test(); } }
result:
Exception in thread "main" java.lang.StackOverflowError at com.coolcoding.boot.oom.StackOverFlowErrorDemo.test(StackOverFlowErrorDemo.java:13) at com.coolcoding.boot.oom.StackOverFlowErrorDemo.test(StackOverFlowErrorDemo.java:13) at com.coolcoding.boot.oom.StackOverFlowErrorDemo.test(StackOverFlowErrorDemo.java:13)
2.java.lang.OutOfMemoryError:Java heap space
For debugging convenience, first set the maximum heap memory and the initial heap memory size
JVM debugging parameter setting and description
-Xms | Initial heap memory | Generally 1 / 16 of the memory |
---|---|---|
-Xms | Maximum heap memory | Generally 1 / 4 of the memory |
Setting: - XMS: 10M- Xmx:10m
Case:
public class JavaHeapSpaceDemo { public static void main(String[] args) { String str = "xxxxxxxxxdddddddddddd"; while (true){ //Loop to create string object str += str + new Random().nextInt(1111111111) + new Random().nextInt(222222222); //Get the string from the constant pool. If it does not exist, create a string and put it into the constant pool str.intern(); } } }
result:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:674) at java.lang.StringBuilder.append(StringBuilder.java:208) at com.coolcoding.boot.oom.JavaHeapSpaceDemo.main(JavaHeapSpaceDemo.java:14)
3.java.lang.OutOfMemoryError:GC overhead limit exceeded
Simple understanding: GC takes too long to recover, and too much time is spent in GC, but the recovery effect is poor.
Principle:
- Recycling too long means that more than 98% of the time is spent on GC and less than 2% of the heap memory is recycled
- The exception will only be thrown in extreme cases when less than 2% of GC is recycled for several consecutive times,
- If no exception is thrown, the memory cleaned by GC will soon fill up here, forcing GC to execute here,
- This forms a vicious circle
JVM parameter settings:
-Xms:10m;-Xmx:10m;-XX:+PrintGCDetails ;-XX:MaxDirectMemory=5m
Case:
public class GCOverheadDemo { public static void main(String[] args) { int i = 0; List<String> list = new ArrayList<>(); try { while (true){ list.add(String.valueOf(++i).intern()); } }catch (Throwable e){ e.printStackTrace(); throw e; } } }
result:
[Full GC (Ergonomics) [PSYoungGen: 2048K->2048K(2560K)] [ParOldGen: 7049K->7046K(7168K)] 9097K->9094K(9728K), [Metaspace: 3886K->3886K(1056768K)], 0.0530256 secs] [Times: user=0.14 sys=0.00, real=0.05 secs] [Full GC (Ergonomics) java.lang.OutOfMemoryError: GC overhead limit exceeded [PSYoungGen: 2048K->2048K(2560K)] [ParOldGen: 7050K->7046K(7168K)] 9098K->9094K(9728K), [Metaspace: 3886K->3886K(1056768K)], 0.0493460 secs] [Times: user=0.13 sys=0.00, real=0.05 secs] [Full GC (Ergonomics) at java.lang.Integer.toString(Integer.java:401) //2048k before recycling - > 2048k after recycling, it can be seen that the GC recycling effect is poor [PSYoungGen: 2048K->2048K(2560K) [Full GC (Ergonomics) [PSYoungGen: 2048K->0K(2560K)] [ParOldGen: 7020K->1119K(7168K)] 9068K->1119K(9728K), [Metaspace: 3892K->3892K(1056768K)], 0.0176793 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] at java.lang.String.valueOf(String.java:3099) at com.coolcoding.boot.oom.GCOverheadDemo.main(GCOverheadDemo.java:16) Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded at java.lang.Integer.toString(Integer.java:401) at java.lang.String.valueOf(String.java:3099) at com.coolcoding.boot.oom.GCOverheadDemo.main(GCOverheadDemo.java:16) Heap
4.java.lang.OutOfMemoryError:Direct buffer memory
Direct memory overflow
Cause analysis:
Direct memory crash, where the meta space is not in the virtual machine, but uses local memory, which has nothing to do with GC.
It is common in NIO programs to use ByteBuffer to read and write data. This is an IO method based on channel and buffer. You can use the native function to directly allocate out of heap memory and operate through the DirectByteBuffer object stored in Java push as a reference to this memory. This method can improve performance in some common because it avoids copying data back and forth between Java heap and native heap.
For example:
ByteBuffer.allocate(capability) | In heap memory | Under the jurisdiction of GC, the speed is relatively slow because it needs to be copied |
---|---|---|
ByteBuffer.allocateDirect(capability) | Local memory | It is not under the jurisdiction of GC, and the speed is fast because there is no need to copy |
If the local memory is allocated continuously and the heap memory is rarely used, the JVM does not need to execute GC, and the directbytebuffer objects will not be recycled. At this time, the heap memory is sufficient, but the local memory is about to be exhausted. If you try to allocate the local memory again, OOM will appear
Configuration parameters:
-Xms:10m;-Xmx:10m; -XX:+PrintGCDetails;+XX:MaxDirectMemorySize=5m
Example:
public class DirectBufferMemoryDemo { public static void main(String[] args) { System.out.println("Local memory = " + (VM.maxDirectMemory() / 1024 / 1024) + "MB"); try{ TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e){e.printStackTrace();} //allocateDirect allocates direct memory ByteBuffer.allocateDirect(6 * 1024 * 1024); } }
result:
"D:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3\lib\idea_rt.jar=49710:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\student.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\workspace\springboot-demo\target\classes;D:\mavenRepository\org\springframework\boot\spring-boot-starter-web\2.2.6.RELEASE\spring-boot-starter-web-2.2.6.RELEASE.jar;D:\mavenRepository\org\springframework\boot\spring-boot-starter\2.2.6.RELEASE\spring-boot-starter-2.2.6.RELEASE.jar;D:\mavenRepository\org\springframework\boot\spring-boot-starter-logging\2.2.6.RELEASE\spring-boot-starter-logging-2.2.6.RELEASE.jar;D:\mavenRepository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\mavenRepository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\mavenRepository\org\apache\logging\log4j\log4j-to-slf4j\2.12.1\log4j-to-slf4j-2.12.1.jar;D:\mavenRepository\org\apache\logging\log4j\log4j-api\2.12.1\log4j-api-2.12.1.jar;D:\mavenRepository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\mavenRepository\org\yaml\snakeyaml\1.25\snakeyaml-1.25.jar;D:\mavenRepository\org\springframework\boot\spring-boot-starter-json\2.2.6.RELEASE\spring-boot-starter-json-2.2.6.RELEASE.jar;D:\mavenRepository\com\fasterxml\jackson\core\jackson-databind\2.10.3\jackson-databind-2.10.3.jar;D:\mavenRepository\com\fasterxml\jackson\core\jackson-annotations\2.10.3\jackson-annotations-2.10.3.jar;D:\mavenRepository\com\fasterxml\jackson\core\jackson-core\2.10.3\jackson-core-2.10.3.jar;D:\mavenRepository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.10.3\jackson-datatype-jdk8-2.10.3.jar;D:\mavenRepository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.10.3\jackson-datatype-jsr310-2.10.3.jar;D:\mavenRepository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.10.3\jackson-module-parameter-names-2.10.3.jar;D:\mavenRepository\org\springframework\boot\spring-boot-starter-validation\2.2.6.RELEASE\spring-boot-starter-validation-2.2.6.RELEASE.jar;D:\mavenRepository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;D:\mavenRepository\org\hibernate\validator\hibernate-validator\6.0.18.Final\hibernate-validator-6.0.18.Final.jar;D:\mavenRepository\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar;D:\mavenRepository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;D:\mavenRepository\org\springframework\spring-web\5.2.5.RELEASE\spring-web-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-beans\5.2.5.RELEASE\spring-beans-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-webmvc\5.2.5.RELEASE\spring-webmvc-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-aop\5.2.5.RELEASE\spring-aop-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-context\5.2.5.RELEASE\spring-context-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-expression\5.2.5.RELEASE\spring-expression-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\boot\spring-boot-devtools\2.2.6.RELEASE\spring-boot-devtools-2.2.6.RELEASE.jar;D:\mavenRepository\org\springframework\boot\spring-boot\2.2.6.RELEASE\spring-boot-2.2.6.RELEASE.jar;D:\mavenRepository\org\springframework\boot\spring-boot-autoconfigure\2.2.6.RELEASE\spring-boot-autoconfigure-2.2.6.RELEASE.jar;D:\mavenRepository\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar;D:\mavenRepository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\mavenRepository\org\springframework\spring-core\5.2.5.RELEASE\spring-core-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-jcl\5.2.5.RELEASE\spring-jcl-5.2.5.RELEASE.jar;D:\mavenRepository\cn\hutool\hutool-all\5.1.0\hutool-all-5.1.0.jar;D:\mavenRepository\org\apache\poi\poi-ooxml\4.1.2\poi-ooxml-4.1.2.jar;D:\mavenRepository\org\apache\poi\poi\4.1.2\poi-4.1.2.jar;D:\mavenRepository\commons-codec\commons-codec\1.13\commons-codec-1.13.jar;D:\mavenRepository\org\apache\commons\commons-collections4\4.4\commons-collections4-4.4.jar;D:\mavenRepository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar;D:\mavenRepository\com\zaxxer\SparseBitSet\1.2\SparseBitSet-1.2.jar;D:\mavenRepository\org\apache\poi\poi-ooxml-schemas\4.1.2\poi-ooxml-schemas-4.1.2.jar;D:\mavenRepository\org\apache\xmlbeans\xmlbeans\3.1.0\xmlbeans-3.1.0.jar;D:\mavenRepository\org\apache\commons\commons-compress\1.19\commons-compress-1.19.jar;D:\mavenRepository\com\github\virtuald\curvesapi\1.06\curvesapi-1.06.jar;D:\mavenRepository\com\101tec\zkclient\0.11\zkclient-0.11.jar;D:\mavenRepository\org\apache\zookeeper\zookeeper\3.4.13\zookeeper-3.4.13.jar;D:\mavenRepository\org\slf4j\slf4j-log4j12\1.7.30\slf4j-log4j12-1.7.30.jar;D:\mavenRepository\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\mavenRepository\jline\jline\0.9.94\jline-0.9.94.jar;D:\mavenRepository\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar;D:\mavenRepository\io\netty\netty\3.10.6.Final\netty-3.10.6.Final.jar;D:\mavenRepository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\mavenRepository\com\google\guava\guava\29.0-jre\guava-29.0-jre.jar;D:\mavenRepository\com\google\guava\failureaccess\1.0.1\failureaccess-1.0.1.jar;D:\mavenRepository\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;D:\mavenRepository\com\google\code\findbugs\jsr305\3.0.2\jsr305-3.0.2.jar;D:\mavenRepository\org\checkerframework\checker-qual\2.11.1\checker-qual-2.11.1.jar;D:\mavenRepository\com\google\errorprone\error_prone_annotations\2.3.4\error_prone_annotations-2.3.4.jar;D:\mavenRepository\com\google\j2objc\j2objc-annotations\1.3\j2objc-annotations-1.3.jar;D:\mavenRepository\com\baomidou\dynamic-datasource-spring-boot-starter\3.0.0\dynamic-datasource-spring-boot-starter-3.0.0.jar;D:\mavenRepository\org\springframework\boot\spring-boot-starter-aop\2.2.6.RELEASE\spring-boot-starter-aop-2.2.6.RELEASE.jar;D:\mavenRepository\org\aspectj\aspectjweaver\1.9.5\aspectjweaver-1.9.5.jar;D:\mavenRepository\mysql\mysql-connector-java\8.0.19\mysql-connector-java-8.0.19.jar;D:\mavenRepository\org\springframework\boot\spring-boot-starter-jdbc\2.2.6.RELEASE\spring-boot-starter-jdbc-2.2.6.RELEASE.jar;D:\mavenRepository\com\zaxxer\HikariCP\3.4.2\HikariCP-3.4.2.jar;D:\mavenRepository\org\springframework\spring-jdbc\5.2.5.RELEASE\spring-jdbc-5.2.5.RELEASE.jar;D:\mavenRepository\org\springframework\spring-tx\5.2.5.RELEASE\spring-tx-5.2.5.RELEASE.jar;D:\mavenRepository\org\mybatis\spring\boot\mybatis-spring-boot-starter\1.3.5\mybatis-spring-boot-starter-1.3.5.jar;D:\mavenRepository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\1.3.5\mybatis-spring-boot-autoconfigure-1.3.5.jar;D:\mavenRepository\org\mybatis\mybatis\3.4.6\mybatis-3.4.6.jar;D:\mavenRepository\org\mybatis\mybatis-spring\1.3.3\mybatis-spring-1.3.3.jar" com.coolcoding.boot.oom.DirectBufferMemoryDemo [GC (Allocation Failure) [PSYoungGen: 2048K->504K(2560K)] 2048K->983K(9728K), 0.0023899 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Local memory = 5MB [GC (Allocation Failure) [PSYoungGen: 2552K->504K(2560K)] 3031K->1543K(9728K), 0.0035927 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (System.gc()) [PSYoungGen: 781K->504K(2560K)] 1820K->1591K(9728K), 0.0013692 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (System.gc()) [PSYoungGen: 504K->0K(2560K)] [ParOldGen: 1087K->1333K(7168K)] 1591K->1333K(9728K), [Metaspace: 4029K->4029K(1056768K)], 0.0155318 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory at java.nio.Bits.reserveMemory(Bits.java:694) at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123) at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311) at com.coolcoding.boot.oom.DirectBufferMemoryDemo.main(DirectBufferMemoryDemo.java:17) Heap PSYoungGen total 2560K, used 53K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000) eden space 2048K, 2% used [0x00000000ffd00000,0x00000000ffd0d748,0x00000000fff00000) from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000) to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000) ParOldGen total 7168K, used 1333K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000) object space 7168K, 18% used [0x00000000ff600000,0x00000000ff74d618,0x00000000ffd00000) Metaspace used 4061K, capacity 4568K, committed 4864K, reserved 1056768K class space used 450K, capacity 460K, committed 512K, reserved 1048576K
5.java.lang.OutOfMemoryError:unable to create new native thread
This exception will occur in the case of high concurrency, which is related to the corresponding platform
Cause analysis:
An application process creates too many threads, exceeding the system load limit. For example, Linux allows a single process to create 1024 threads by default.
resolvent:
- Reduce the number of threads created by the application, analyze whether the application really needs to create so many threads, and minimize the number of threads
- Modify the server configuration, such as Linux server configuration, and expand the default limit of Linux
Case:
public class UnableCreateNewThreadDemo { public static void main(String[] args) { //Keep creating threads for loops for (int i = 0; ; i++) { new Thread(()->{ //Set integer MAX_ Value to keep the thread running try{ TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);}catch (InterruptedException e){e.printStackTrace();} }).start(); } } }
Test:
Upload the file to linux
Execute javac -d file name
Execute java package name Start test application with file name
When the system load is reached, Java. Net will be thrown lang.OutOfMemoryError:unable to create new native thread
To modify the system configuration, you can first view the thread limit of the corresponding user
View the thread limit of the corresponding user under linux
//View limit number ulimit -u //Edit and modify vim /etc/security/limits.d/90-nproc.conf
Such as modifying the configuration of z3 users
6.java.lang.OutOfMemoryError:Metaspace
Execute the following command in cmd to view the default basic configuration of JVM parameters and the size of metaspaceSize
java -XX:+PrintFlagsInitial
metaspace stores data: (permanently replaced by metaspace after JAVA8)
- Class information loaded by virtual machine
- Constant pool
- Static variable
- Even compiled code
JVM parameter configuration
-XX:MetaspaceSize=8m -XX:MAXMetaspaceSize=8m
Case:
public class MetaspaceOOMTest { //Prepare a static class static class OOMTest { } ; public static void main(String[] args) { int i = 0; try { while (true) { //Loop continuously creates static classes to fill the space of metaspace i++; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMTest.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invoke(o, args); } }); enhancer.create(); } } catch (Exception e) { //Record how many static classes OOMTest have been created System.out.println(i + "Exception after times"); e.printStackTrace(); } } }
result:
279 Exception after times org.springframework.cglib.core.CodeGenerationException: java.lang.OutOfMemoryError-->Metaspace at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:538) at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363) at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:131) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:569) at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:384) at com.coolcoding.boot.oom.MetaspaceOOMTest.main(MetaspaceOOMTest.java:34) Caused by: java.lang.OutOfMemoryError: Metaspace at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:535) ... 7 more