栈与堆

栈与堆

  • 栈:栈内存、主管程序的运行、生命周期和线程同步。先进后出

  • 栈内存 : 8大基本数据类型、对象的引用、实例的方法

  • 线程执行完,栈内存释放。所以说栈没有垃圾回收。

  • 一旦线程结束,栈就OVER!

  • 三种JVM

    • Sun公司的HotSpot :Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
    • Orache JRockit,原先叫Bea JRockit
    • IBM

Heap,一个JVM只有一个堆内存,并且堆内存的大小是可以调节的
类加载器读取文件一般会把类、方法、常量、变量保存我们所引用的真实对象到堆中
堆中还分三个区域:

  • 新生区/伊甸园区 EdenSpace
  • 养老区
  • 永久区

img

  • 堆内存溢出(OOM错误)

public class Demo01 {
    public static void main(String[] args) {
       String test = "堆内存溢出==================================";
       while (true){
           test += test + new Random().nextInt(00000000)+ new Random().nextInt(11111111);
       }
    }
}

/*Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2882)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:597)
    at java.lang.StringBuilder.append(StringBuilder.java:212)
    at com.saxon.jvm.Demo01.main(Demo01.java from InputFileObject:9)*/
  • 新生区、永久区、堆内存调优

    • 新生区

      • 新创建的对象在这里
      • 如果对象没有被GC垃圾回收则会进入幸存者0/1区【新生区和老年区内存满了就会由重量级GC垃圾回收,一般情况下不会进入老年区】
      • 百分之99的对象都是临时的

img

    • 永久区:这个区域常驻内存的,用来存放jdk自身携带的Class对象,interface元数据,存储的是java运行时的一些环境。这个区域不存在垃圾回收。关闭JVM会关闭该区域的内存。

      比如:一个启动类,加载了大量的jar包。或者Tomcat部署了太多应用,大量动态生成的反射类,不断地被加载。知道内存溢出OOM.

      • jdk1.6 之前:永久代,常量池在方法区。
      • jdk1.7 : 永久代,但是慢慢退化,去永久代,常量池在堆中。
      • jdk1.8:无永久代,常量池在元空间。
      public static void main(String[] args) {
          //获取运行时想用的最大内存
          long max = Runtime.getRuntime().maxMemory();  //字节
          //获取使用的总内存
          long total = Runtime.getRuntime().totalMemory();
          //可用处理器的个数
          int availableProcessors = Runtime.getRuntime().availableProcessors();
          System.out.println(max+"字节也就是"+(double)(max/1024/1024)+"兆");
          System.out.println(total+"字节也就是"+(double)(total/1024/1024)+"兆");
          System.out.println(availableProcessors);
      }
      
      //默认情况下:分配的内存是电脑内存的1/4,而初试内存只占1/64.
      //结果:
      3810328576字节也就是3633.0兆
      256770048字节也就是244.0兆
      4
      
  • 手动配置堆内存: -Xms1024m -Xmx1024m -XX:+PrintGCDetails

    • Xms : 配置当前程序能够运行的最大内存大小,不能超过本机内存
    • Xmx:当前程序初始化内存占的大小,值越大启动性越高。
public static void main(String[] args) {
    //-Xms1024m -Xmx1024m -XX:+PrintGCDetails
    
    //获取运行时想用的最大内存
    long max = Runtime.getRuntime().maxMemory();  //字节
    //获取使用的总内存
    long total = Runtime.getRuntime().totalMemory();
    //可用处理器的个数
    int availableProcessors = Runtime.getRuntime().availableProcessors();
    System.out.println(max+"字节也就是"+(double)(max/1024/1024)+"兆");
    System.out.println(total+"字节也就是"+(double)(total/1024/1024)+"兆");
    System.out.println(availableProcessors);
}

//运行结果:
1029046272字节也就是981.0兆  = 年轻区 + 老年区
1029046272字节也就是981.0兆
4
Heap (堆)
 PSYoungGen(年轻区)      total 305856K, used 15732K [0x00000000eaab0000, 0x0000000100000000, 0x0000000100000000)
  eden space 262208K, 6% used [0x00000000eaab0000,0x00000000eba0d280,0x00000000faac0000)
  from space 43648K, 0% used [0x00000000fd560000,0x00000000fd560000,0x0000000100000000)
  to   space 43648K, 0% used [0x00000000faac0000,0x00000000faac0000,0x00000000fd560000)
 PSOldGen  (老年区)      total 699072K, used 0K [0x00000000c0000000, 0x00000000eaab0000, 0x00000000eaab0000)
  object space 699072K, 0% used [0x00000000c0000000,0x00000000c0000000,0x00000000eaab0000)
 PSPermGen (元空间)      total 21248K, used 3459K [0x00000000bae00000, 0x00000000bc2c0000, 0x00000000c0000000)
  object space 21248K, 16% used [0x00000000bae00000,0x00000000bb160c38,0x00000000bc2c0000)
  • 解决OOM

      1. 尝试扩大堆内存
      2. 分析内存,看一下哪个地方出现问题(专业工具):下期文章
public class Demo01 {
    //修改堆内存:-Xms8m -Xmx8m -XX:+PrintGCDetails
    public static void main(String[] args) {
        String test = "堆内存溢出==================================";
        while (true){
            test += test + new Random().nextInt(22222222)+ new Random().nextInt(11111111);
        }
    }
}

//运行结果
//轻量级GC回收
[GC [PSYoungGen: 2036K->311K(2368K)] 2036K->534K(7872K), 0.0005685 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 1690K->311K(2368K)] 1913K->964K(7872K), 0.0024461 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 2063K->128K(2368K)] 2716K->1641K(7872K), 0.0004997 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 1910K->160K(2368K)] 5144K->4254K(7872K), 0.0006006 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 1033K->160K(2240K)] 5127K->5114K(7744K), 0.0015555 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//重量级GC回收
[Full GC [PSYoungGen: 160K->0K(2240K)] [PSOldGen: 4954K->2033K(5504K)] 5114K->2033K(7744K) [PSPermGen: 3569K->3569K(21248K)], 0.0040491 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 1808K->0K(2240K)] [PSOldGen: 5474K->4614K(5504K)] 7282K->4614K(7744K) [PSPermGen: 3686K->3686K(21248K)], 0.0043998 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC [PSYoungGen: 1732K->0K(2240K)] [PSOldGen: 4614K->2033K(5504K)] 6346K->2033K(7744K) [PSPermGen: 3686K->3686K(21248K)], 0.0038535 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 1736K->0K(2240K)] [PSOldGen: 5474K->5357K(5504K)] 7210K->5357K(7744K) [PSPermGen: 3717K->3716K(21248K)], 0.0061004 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC [PSYoungGen: 0K->0K(1856K)] 5357K->5357K(7360K), 0.0001355 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 0K->0K(1856K)] [PSOldGen: 5357K->5337K(5504K)] 5357K->5337K(7360K) [PSPermGen: 3716K->3707K(21248K)], 0.0050888 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 1856K, used 97K [0x00000000ffd60000, 0x0000000100000000, 0x0000000100000000)
  eden space 1408K, 6% used [0x00000000ffd60000,0x00000000ffd78400,0x00000000ffec0000)
  from space 448K, 0% used [0x00000000fff90000,0x00000000fff90000,0x0000000100000000)
  to   space 640K, 0% used [0x00000000ffec0000,0x00000000ffec0000,0x00000000fff60000)
 PSOldGen        total 5504K, used 5337K [0x00000000ff800000, 0x00000000ffd60000, 0x00000000ffd60000)
  object space 5504K, 96% used [0x00000000ff800000,0x00000000ffd367f0,0x00000000ffd60000)
 PSPermGen       total 21248K, used 3823K [0x00000000fa600000, 0x00000000fbac0000, 0x00000000ff800000)
  object space 21248K, 17% used [0x00000000fa600000,0x00000000fa9bc160,0x00000000fbac0000)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:2882)
	at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:597)
	at java.lang.StringBuilder.append(StringBuilder.java:212)
	at com.saxon.jvm.Demo01.main(Demo01.java from InputFileObject:11)
posted @ 2021-04-30 10:42  saxon宋  阅读(93)  评论(0)    收藏  举报