Java——JVM内存详解

49 篇文章 6 订阅
订阅专栏

1. 简介

Java 程序运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

分配:通过关键字new创建对象分配内存空间,对象存在堆中。
释放 :对象的释放是由垃圾回收机制决定和执行的

JVM的内存可分为3个区:

  • 堆(heap)
  • 栈(stack)
  • 方法区(method,也叫静态区):

2. 内存区域的划分

一个java程序运行的数据区:
在这里插入图片描述
在这里插入图片描述

堆区: 程序员自己申请,运行时线程公有

  • 通过new生成的对象都存放在堆中,对于堆中的对象生命周期的管理由Java虚拟机的垃圾回收机制GC进行回收和统一管理
  • jvm只有一个堆区(heap),且被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身和数组本身;
  • 优点是可以动态分配内存大小,缺点是由于动态分配内存导致存取速度慢。

虚拟机栈: 系统自己分配,运行时线程私有

  • 栈内存主要是存放一些基本类型的变量和对象的引用变量。最典型的就是我们new一个对象时,对象名作为变量就存放在栈内存中
  • 栈内存有一个很重要的特殊性——在栈中的数据可以共享(已存在的值不会再次创建)
    int a = 3;
    int b = 3;
    (编译器先处理int a =3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b)
  • 每个方法执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等。局部变量表存放了编译器可知的各种基本数据类型、对象引用和returnAddress类型
  • 每个方法从调用直至完成的过程,都对应着一个栈帧从入栈到出栈的过程。每当一个方法执行完成时,该栈帧就会弹出栈帧的元素作为这个方法的返回值,并且清除这个栈帧,Java栈的栈顶的栈帧就是当前正在执行的活动栈,也就是当前正在执行的方法,方法的调用过程也是由栈帧切换来产生结果。
  • 在JVM规范中,对这个区域规定了两种异常情况:
    1.如果线程请求的栈深度大于虚拟机允许的深度,将抛出StackOverflowError异常;
    2.如果虚拟机栈可以动态扩展,在扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

本地方法栈:
和虚拟机栈所发挥的作用基本一致,不同的是:

  • 虚拟机栈为虚拟机执行Java方法(字节码)服务
  • 本地方法栈则为虚拟机使用到的Native方法服务
  • 本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

方法区(静态区):

  • 是各个线程共享的内存区域,它用于存储class二进制文件,包含所有的class和static变量,包含了虚拟机加载的类信息、常量(常量池)、静态变量(静态域)、即时编译后的代码等数据。
  • 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
  • 被所有的线程共享,方法区包含所有的class(class是指类的原始代码,要创建一个类的对象,首先要把该类的代码加载到方法区中,并且初始化)和static变量。
  • 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
    常量池:在编译期间就将一部分数据存放于该区域,包含以final修饰的基本数据类型的常量值、String字符串。(在java6时它是方法区的一部分;1.7又把他放到了堆内存中;1.8之后出现了元空间,它又回到了方法区。)
    静态域:存放类中以static声明的静态成员变量。
    程序计数器:当前线程所执行的行号指示器。通过改变计数器的值来确定下一条指令,比如循环,分支,跳转,异常处理,线程恢复等都是依赖计数器来完成。

程序计数器:
一个非常小的内存空间,用来保存程序执行到的位置(线程私有),它可以看作是当前线程所执行的字节码的行号指示器。

Metaspace元空间:

  • 在JDK1.8中,永久代已经不存在,存储的类信息、编译后的代码数据等已经移动到了MetaSpace(元空间)中,元空间并没有处于堆内存上,而是直接占用的本地内存(NativeMemory)。
  • 元空间的本质和永久代类似,都是对JVM规范中方法区的实现。
  • 元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。
  • 元空间的大小仅受本地内存限制,可以指定元空间大小。
  • Java8为什么要将永久代替换成Metaspace?
    1、字符串存在永久代中,容易出现性能问题和内存溢出。
    2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
    3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
    4、Oracle 可能会将HotSpot 与 JRockit 合二为一。

3. 举个栗子

(1)基本数据类型

int a = 3;
int b = 3;

编译器先处理 int a = 3;首先它会在栈中创建一个变量为 a 的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将 a 指向3的地址。

接着处理 int b = 3;在创建完 b 这个引用变量后,由于在栈中已经有3这个字面值,便将 b 直接指向3的地址。这样,就出现了 a 与 b 同时均指向3的情况。

(2)对象

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

一个类通过使用new运算符可以创建多个不同的对象实例,这些对象实例将在堆中被分配不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态。

        Person one = new Person("小明",15);
        Person two = new Person("小王",17);

在堆内存中只创建了一个对象实例,在栈内存中创建了两个对象引用,两个对象引用同时指向一个对象实例。

        Person one = new Person("小明",15);
        Person two = one;

(3)包装类
基本类型的定义都是直接在栈中,如果用包装类来创建对象,就和普通对象一样了。

比如int a = 5,a存储在栈中。

而Integer i = new Integer(5),i 对象数据存储在堆中,i 的引用存储在栈中。

(4)数组
数组是一种引用类型,数组用来存储同一种数据类型的数据。

一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间仍然保留,因此数组长度将不能被改变。

int[] array = new int[5]

首先会在栈中创建引用变量,在堆中开辟5个int型数据的空间,该引用变量存放数组首地址,即实现数组名来引用数组。

4. JVM内存模型

在这里插入图片描述
在这里插入图片描述
主要变化在于:

  • java8没有了永久代(虚拟内存),替换为了元空间(本地内存)。
  • 常量池:1.7又把他放到了堆内存中;1.8之后出现了元空间,它又回到了方法区。

年轻代:

  • 新生成的对象都放在年轻代,主要存放一些生命周期比较短的对象
  • 新生代一般分三个区:一个Eden区,两个 Survivor区:
    大部分对象在Eden区中生成,当Eden区满时,还存活的对象将被复制到Survivor区,当这个 Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制到老年代(Tenured)。
    同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。

老年代:
在年轻代中经历多次垃圾回收后仍存活的对象会被放入老年代中,一般存放生命周期较长的对象

java7永久代:
用于存放静态文件,如Java类、方法等。永久带对垃圾回收没有显著影响,一般不做垃圾回收,在JVM内存中划分空间。

java8元空间:
类似于永久带,不过它是直接使用物理内存而不占用JVM堆内存。

5. 垃圾回收机制

Java不用像C++一样自己释放内存,通过垃圾回收器GC来进行内存的回收释放。

  • 不需要进行垃圾回收:程序计数器、JVM栈、本地方法栈。
  • 需要进行回收垃圾的区:堆和方法区

什么时候进行垃圾回收?

  • 该类的所有实例对象都已经被回收。
  • 加载该类的ClassLoader已经被回收。
  • 该类对应的反射类java.lang.Class对象没有被任何地方引用。

几种垃圾收集器:

  • Minor GC:新生代GC,即发生在新生代(包括Eden区和Survivor区)的垃圾回收操作,当新生代无法为新生对象分配内存空间的时候,会触发Minor GC。因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。
  • Major GC:Tenured区GC,用于回收老年代,出现Major GC通常会出现至少一次Minor GC。
  • Full GC:是针对整个新生代、老生代、元空间(metaspace,java8以上版本取代perm gen)的全局范围的GC。Full GC不等于Major GC,也不等于Minor GC+Major GC,发生Full GC需要看使用了什么垃圾收集器组合,才能解释是什么样的垃圾回收。

垃圾回收机制流程如下:
在这里插入图片描述
GC主要处理的是年轻代与老年代的内存清理操作,元空间(永久代)一般很少用GC。具体流程如下:

① 当一个新对象产生,需要内存空间,为该对象进行内存空间申请。

② 首先判断Eden区是否有有内存空间,有的话直接将新对象保存在Eden区。

③ 如果此时Eden区内存空间不足,会自动触发MinorGC,将Eden区不用的内存空间进行清理,清理之后判断Eden区内存空间是否充足,充足的话在Eden区分配内存空间。

④ 如果执行MinerGC发现Eden区不足,判断存活区,如果Survivor区有剩余空间,将Eden区部分活跃对象保存在Survivor区,随后继续判断Eden区是否充足,如果充足在Eden区进行分配。

⑤ 如果此时Survivor区也没空间了,继续判断老年区,如果老年区空间充足,则将Survivor区中活跃对象保存到老年代,而后存活区有空余空间,随后Eden区将活跃对象保存在Survivor区之中,在Eden区为新对象开辟空间。

⑥ 如果老年代满了,此时将产生MajorGC进行老年代内存清理,进行完全垃圾回收。

⑦ 如果老年代执行MajorGC发现依然无法进行对象保存,此时会进行OOM异常(OutOfMemoryError)。

上面流程就是整个垃圾回收机制流程,总的来说,新创建的对象一般都会在Eden区生成,除非这个创建对象太大,那有可能直接在老年区生成。

几种垃圾回收算法:

  • 标记-清除算法(Mark-Sweep):最基础的GC算法,将需要进行回收的对象做标记,之后扫描,有标记的进行回收,这样就产生两个步骤:标记和清除。这个算法效率不高,而且在清理完成后会产生内存碎片,这样,如果有大对象需要连续的内存空间时,还需要进行碎片整理。
  • 复制算法(Copying):新生代内存分为了三份,Eden区和2块Survivor区,保证有一块Survivor区是空闲的,这样,在垃圾回收的时候,将不需要进行回收的对象放在空闲的Survivor区,然后将Eden区和第一块Survivor区进行完全清理,这样有一个问题,就是如果第二块Survivor区的空间不够大怎么办?这个时候,就需要当Survivor区不够用的时候,暂时借持久代的内存用一下。此算法适用于新生代。
  • 标记-整理(或叫压缩)算法(Mark-Compact):和标记-清楚算法前半段一样,只是在标记了不需要进行回收的对象后,将标记过的对象移动到一起,使得内存连续,这样,只要将标记边界以外的内存清理就行了。此算法适用于持久代。

6. 其他关于内存的小知识点

(1)Java中==和equals的区别,equals和hashCode的区别

  • Java中==和equals的区别,equals和hashCode的区别
  • ==用于基本数据类型用比较,比较的是值是否相等
  • ==用于对象,比较的是在内存中的地址是否相等
  • Equals表示引用所指内容是否相等。
javajvm及其内存分布
weixin_64702703的博客
08-09 297
JVMJAVA Virtual Machine的简称,意为java虚拟机,虚拟机指通过软件来模拟具有完整硬件功能的,运行在一个完全隔离的环境中的完整计算机系统(相当于被定制的一台不存在的计算机)
JVM内存结构详解
01-20
文章目录一、你了解JVM内存结构吗在这之前需要知道JVM内存结构图——JDK1.81.1、程序计数器1.2、虚拟机栈(JVM Stack)1.1.1、java.lang.StackOverflowError问题1.3、本地方法栈1.4、元空间(MetaSpace)1.4.1、...
Java基础之JVM对象内存分配机制简介
最新发布
磊杰的博客
04-21 1011
大量对象分配在Eden区,Eden区满了后会触发MinorGC,可能99%以上的对象会变成垃圾而被回收掉,而剩余存活的对象会被挪到空的Survivor0区,下次Eden区满后会触发MinorGC,把Eden区+Survivor0区中存活的对象复制到Survivor区,并Eden区和Survivor区垃圾回收,因此新生代的对象大部分是朝生夕死,存活时间比较多,所以JVM默认的8:1:1比例很合适,原则:让Eden区尽量大,Survivor区足够用就可以;
JVMJVM内存模型详解
热门推荐
Money、坤的博客
08-24 1万+
JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运行,这也是Java能够“一次编译,到处运行的”原因。方法区存储的内容有:类型信息(比如类全称、父类全称)、域信息(域名称、域修饰符private等)、方法信息(方法名称、方法修饰符、返回类型等)、字面量(字面量包括文本字符串、八种基本类型的值 、被声明为final的常量等)。Java虚拟机栈是当前线程在执行方法时存储所需的数据、指令、返回地址的一种栈结构(先进后出)。
大吉大利 :空投十个JVM核心知识点,速度捡包
sowhat
12-21 955
JVM内存模型、可达性分析、GC算法、三色标记、GC流程、GC回收器、CMS、G1、new对象流程、ClassLoader、OOM、CPU100%、GC调优
JVM内存
weixin_56390908的博客
07-19 117
JVM内存空间分为堆内存、栈内存、方法区三大部分
JVM 基础 (1) -- Java内存结构
南京的博客
03-16 691
以黄小斜博文为主的学习总结 文章目录1.简介1. 了解 JVM 内存有什么好处2. JVM 主要组成成分 1.简介 1. 了解 JVM 内存有什么好处 所有的 Java 开发人员可能会遇到这样的困惑:我该为堆内存设置多大空间呢?OutOfMemoryError 的异常到底涉及到运行时数据区的哪块区域?该怎么解决呢? 其实如果你经常解决服务器性能问题,那么这些问题就会变的非常常见,了解 JVM 内存...
Java 详解JVM) 垃圾回收机制原理(csdn)————程序.pdf
12-01
Java 详解JVM) 垃圾回收机制原理(csdn)————程序
Java归约功能功能详解.pdf
07-02
例如,如果程序循环遍历数组中的所有元素,JVM 就可以优化数组的边界检查,使循环更快,展开循环能提供额外的加速。但如果循环是为了找到特定元素,那目前还没有什么优化的办法,使得遍历数组和采用HashMap 的版本...
Java默认方法功能详解.pdf
07-02
例如,如果程序循环遍历数组中的所有元素,JVM 就可以优化数组的边界检查,使循环更快,展开循环能提供额外的加速。但如果循环是为了找到特定元素,那目前还没有什么优化的办法,使得遍历数组和采用HashMap 的版本...
java获得jvm内存大小
12-18
java获得jvm内存大小
Java构建流功能详解.pdf
07-02
例如,如果程序循环遍历数组中的所有元素,JVM 就可以优化数组的边界检查,使循环更快,展开循环能提供额外的加速。但如果循环是为了找到特定元素,那目前还没有什么优化的办法,使得遍历数组和采用HashMap 的版本...
JVM内存详解
qq_36005199的博客
03-05 150
java指令 class解释称机器指令 javap -v xxx.class | class -> 可读文件 javac xxx.java | java -> class 编译器和JIT的区别 编译器: 这个东西第一代jvm就有了,他可以解释字节码文件,但是效率不高,因为每次执行都会从头开始编译执行代码,消耗资源 JIT: 这个东西呢就是解决上面编译器的难处,他提供了一个缓存,能够存储编译过后的机器码指令,这样就不用每次执行代码都去编译 一次,他也只会缓存热点执行代码,避免
浅谈Java内存模型——JVM
moneywenxue的博客
09-24 920
一、前言 二、JVM组成 类加载器(classLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) 本地库接口(Navite Interface) 各个组成部分的用途: 程序在运行之前会把.java文件转成.class的字节码文件,jvm首先通过类加载器(classLoader)把字节码文件加载到内存——运行时数据区(Runtime Data Area),而字节码文件是jvm的一套指令集规范,底层系统并不能识别,需要调用执行引擎(.
JVMjava 虚拟机)内存设置
m0_67402914的博客
04-20 1万+
个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈 一、设置JVM内存设置 1. 设置JVM内存的参数有四个: -XmxJava Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定; -XmsJava Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值; -XmnJava Heap Young区大小,不熟悉最好保留默认值; -Xss每个线程的Stack大小,不熟悉最好保留默认值; 2. 如何设.
什么是JVM内存模型
学亮编程手记
02-10 841
Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。 本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他...
JVM内存概念
lg491733638
05-17 294
1. JVM内存区域分配 堆 Java堆是各线程共享的内存区域,在JVM启动时创建,这块区域是JVM中最大的, 用于存储应用的对象和数组,也是GC主要的回收区,一个 JVM 实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,以方便执行器执行,堆内存分为三部分:新生代、老年代、永久代。 说明: Jdk1.6及之前:常量池分配在永久代 。 Jdk1.7:有,但已经逐步“去永久代” 。 Jdk1.8及之后:无永久代,改用元空间代替(java.lang.O
MyEclipse设置JVM内存大小
不见长安见晨雾
09-13 2328
开发项目遇到错误: java.lang.OutOfMemoryError: PermGen space 大概原因就是内存不够大,具体我也不了解,如下设置解决问题: -Xmx1024M -Xms512M -XX:MaxPermSize=256m
centos7 库容javajvm内存
01-20
在CentOS 7上,可以通过以下步骤来调整JavaJVM内存: 1. 打开Java应用程序的启动脚本文件,通常是以`.sh`或`.bat`为后缀的文件。 2. 在脚本文件中找到设置JVM参数的地方,一般是通过`JAVA_OPTS`或`JAVA_OPTIONS`环境变量来设置。 3. 在环境变量中添加`-Xms`和`-Xmx`参数来设置初始堆大小和最大堆大小。例如,`-Xmx1024m`表示最大堆大小为1GB。 4. 保存并关闭脚本文件。 5. 重新启动Java应用程序,新的JVM内存设置将生效。 请注意,JVM内存的设置应根据应用程序的需求和服务器的可用内存进行调整。过小的内存设置可能导致应用程序性能下降或内存溢出,而过大的内存设置可能浪费服务器资源。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • Android——Handler详解 63850
  • Android进阶——AIDL详解 22328
  • Android——Binder机制 17565
  • Java——ArrayList基本使用 13570
  • Android学习笔记——归纳整理 8437

分类专栏

  • LeetCode 198篇
  • 算法 7篇
  • 设计模式 9篇
  • 一些总结 3篇
  • C++ 1篇
  • JAVA笔记 49篇
  • Android 42篇
  • Kotlin 1篇
  • Python笔记 1篇
  • 遇到的小问题 4篇
  • 日常偷懒 1篇

最新评论

  • Android——使用Intent打开第三方应用

    電話と海と私。: 用resolveActivityInfo还是不行啊,用resolveActivity遇到没有Activity的直接崩溃。resolveActivityInfo把原本有Activity,resolveActivity可以正常打开的都识别成为了false了

  • Android——ContentProvider详解

    丨康有为丨: 详细表情包

  • Android——Handler详解

    欢迎一起学习: 太厉害了,大牛,说的那么全面又那么详细

  • Android——Binder机制

    扶我起来_: 作者强的离谱

  • Android——Handler详解

    往事不可追啊: 厉害了 大神表情包

最新文章

  • Android——定时器轮询
  • Android——protobuf的简单使用
  • Android——应用进程和应用生命周期
2022年2篇
2021年296篇
2020年11篇
2019年1篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yawn__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

深圳SEO优化公司南阳英文网站建设推荐济源建站公司和田关键词按天扣费公司广东网页制作多少钱延安百搜标王哪家好佛山关键词排名包年推广宁德高端网站设计多少钱黔东南百度网站优化排名公司塔城百度标王哪家好河池网站开发大丰网站建设设计公司塔城推广网站多少钱海口阿里店铺托管厦门建网站价格海南网站排名优化价格开封至尊标王那曲seo网站推广推荐深圳网络营销公司林芝网站推广方案推荐山南模板制作价格崇左网站seo优化报价贵港百姓网标王襄阳设计公司网站赤峰网站制作设计公司临沧seo推荐孝感网站优化推广推荐白城企业网站制作公司渭南企业网站设计报价郑州网络广告推广多少钱保定企业网站设计多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化