JVM参数

JVM参数分类

  • 标准参数
    功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数
  • X参数
    非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索 (Options that begin with -X are non-standard (not guaranteed to be supported on all VM implementations), and are subject to change without notice in subsequent releases of the JDK.)
  • XX参数
    非标准 很长一段时间不会列出来 用于JVM开发的debug和调优(Options that are specified with -XX are not stable and are subject to change without notice.)

一些X参数

参数名称含义备注
-Xbatch禁用后台编译
-Xbootclasspath/a:<以 ; 分隔的目录和 zip/jar 文件>附加在引导类路径末尾
-Xcheck:jni对 JNI 函数执行其他检查
-Xcomp在首次调用时强制编译方法
-Xdebug为实现向后兼容而提供
-Xdiag显示附加诊断消息
-Xfuture启用最严格的检查, 预期将来的默认值
-Xint仅解释模式执行
-Xinternalversion显示比 -version 选项更详细的 JVM版本信息
-Xloggc:将 GC 状态记录在文件中 (带时间戳)
-Xmixed混合模式执行 (默认值)
-Xmn为年轻代 (新生代) 设置初始和最大堆大小(以字节为单位)eden+ 2 survivor space
-Xms设置初始 Java 堆大小默认值物理内存的1/64(<1GB),默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx设置最大 Java 堆大小物理内存的1/4(<1GB),默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xnoclassgc禁用类垃圾收集
-Xrs减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xshare:auto在可能的情况下使用共享类数据 (默认值)
-Xshare:off不尝试使用共享类数据
-Xshare:on要求使用共享类数据, 否则将失败。
-XshowSettings显示所有设置并继续
-XshowSettings:all显示所有设置并继续
-XshowSettings:locale显示所有与区域设置相关的设置并继续
-XshowSettings:properties显示所有属性设置并继续
-XshowSettings:vm显示所有与 vm 相关的设置并继续
-Xss设置 Java 每个线程堆栈大小
-Xverify设置字节码验证器的模式
–add-reads <模块>=<目标模块>(,<目标模块>)*更新 <模块> 以读取 <目标模块>, 而无论 模块声明如何。<目标模块> 可以是 ALL-UNNAMED 以读取所有未命名模块。
–add-exports <模块>/<程序包>=<目标模块>(,<目标模块>)*更新 <模块> 以将 <程序包> 导出到 <目标模块>,而无论模块声明如何。<目标模块> 可以是 ALL-UNNAMED 以导出到所有未命名模块。
–add-opens <模块>/<程序包>=<目标模块>(,<目标模块>)*更新 <模块> 以在 <目标模块> 中打开 <程序包>, 而无论模块声明如何。
–illegal-access=<值>允许或拒绝通过未命名模块中的代码对命名模块中的类型成员进行访问。<值> 为 “deny”, “permit”, “warn” 或 “debug” 之一此选项将在未来发行版中删除。
–limit-modules <模块名>[,<模块名>…]限制可观察模块的领域
–patch-module <模块>=<文件>(;<文件>)*使用 JAR 文件或目录中的类和资源覆盖或增强模块。
–disable-@files禁止进一步扩展参数文件

###一些XX参数

Default values are listed for Java SE 6 for Solaris Sparc with -server. Some options may vary per architecture/OS/JVM version. Platforms with a differing default value are listed in the description.

Boolean options are turned on with -XX:+ and turned off with -XX:-.Disa
Numeric options are set with -XX:=. Numbers can include ‘m’ or ‘M’ for megabytes, ‘k’ or ‘K’ for kilobytes, and ‘g’ or ‘G’ for gigabytes (for example, 32k is the same as 32768).
String options are set with -XX:=, are usually used to specify a file, a path, or a list of commands

####行为参数

参数名称和默认值含义
-XX:-AllowUserSignalHandlersDo not complain if the application installs signal handlers. (Relevant to Solaris and Linux only.)
-XX:AltStackSize=16384Alternate signal stack size (in Kbytes). (Relevant to Solaris only, removed from 5.0.)
-XX:-DisableExplicitGCBy default calls to System.gc() are enabled (-XX:-DisableExplicitGC). Use -XX:+DisableExplicitGC to disable calls to System.gc(). Note that the JVM still performs garbage collection when necessary.
-XX:+FailOverToOldVerifierFail over to old verifier when the new type checker fails. (Introduced in 6.)
-XX:+HandlePromotionFailureThe youngest generation collection does not require a guarantee of full promotion of all live objects. (Introduced in 1.4.2 update 11) [5.0 and earlier: false.]
-XX:+MaxFDLimitBump the number of file descriptors to max. (Relevant to Solaris only.)
-XX:PreBlockSpin=10Spin count variable for use with -XX:+UseSpinning. Controls the maximum spin iterations allowed before entering operating system thread synchronization code. (Introduced in 1.4.2.)
-XX:-RelaxAccessControlCheckRelax the access control checks in the verifier. (Introduced in 6.)
-XX:+ScavengeBeforeFullGCDo young generation GC prior to a full GC. (Introduced in 1.4.1.)
-XX:+UseAltSigsUse alternate signals instead of SIGUSR1 and SIGUSR2 for VM internal signals. (Introduced in 1.3.1 update 9, 1.4.1. Relevant to Solaris only.)
-XX:+UseBoundThreadsBind user level threads to kernel threads. (Relevant to Solaris only.)
-XX:-UseConcMarkSweepGCUse concurrent mark-sweep collection for the old generation. (Introduced in 1.4.1)
-XX:+UseGCOverheadLimitUse a policy that limits the proportion of the VM’s time that is spent in GC before an OutOfMemory error is thrown. (Introduced in 6.)
-XX:+UseLWPSynchronizationUse LWP-based instead of thread based synchronization. (Introduced in 1.4.0. Relevant to Solaris only.)
-XX:-UseParallelGCUse parallel garbage collection for scavenges. (Introduced in 1.4.1)
-XX:-UseParallelOldGCUse parallel garbage collection for the full collections. Enabling this option automatically sets -XX:+UseParallelGC. (Introduced in 5.0 update 6.)
-XX:-UseSerialGCUse serial garbage collection. (Introduced in 5.0.)
-XX:-UseSpinningEnable naive spinning on Java monitor before entering operating system thread synchronizaton code. (Relevant to 1.4.2 and 5.0 only.) [1.4.2, multi-processor Windows platforms: true]
-XX:+UseTLABUse thread-local object allocation (Introduced in 1.4.0, known as UseTLE prior to that.) [1.4.2 and earlier, x86 or with -client: false]
-XX:+UseSplitVerifierUse the new type checker with StackMapTable attributes. (Introduced in 5.0.)[5.0: false]
-XX:+UseThreadPrioritiesUse native thread priorities.
-XX:+UseVMInterruptibleIOThread interrupt before or with EINTR for I/O operations results in OS_INTRPT. (Introduced in 6. Relevant to Solaris only.)

####G1参数

参数名称和默认值含义
-XX:+UseG1GCUse the Garbage First (G1) Collector
-XX:MaxGCPauseMillis=nSets a target for the maximum GC pause time. This is a soft goal, and the JVM will make its best effort to achieve it.
-XX:InitiatingHeapOccupancyPercent=n?----Percentage of the (entire) heap occupancy to start a concurrent GC cycle. It is used by GCs that trigger a concurrent GC cycle based on the occupancy of the entire heap, not just one of the generations (e.g., G1). A value of 0 denotes ‘do constant GC cycles’. The default value is 45.
-XX:NewRatio=nRatio of old/new generation sizes. The default value is 2.
-XX:SurvivorRatio=nRatio of eden/survivor space size. The default value is 8.
-XX:MaxTenuringThreshold=n?----晋升阈值Maximum value for tenuring threshold. The default value is 15.
-XX:ParallelGCThreads=nSets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running.
-XX:ConcGCThreads=nNumber of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running.
-XX:G1ReservePercent=nSets the amount of heap that is reserved as a false ceiling to reduce the possibility of promotion failure. The default value is 10.
-XX:G1HeapRegionSize=nWith G1 the Java heap is subdivided into uniformly sized regions. This sets the size of the individual sub-divisions. The default value of this parameter is determined ergonomically based upon heap size. The minimum value is 1Mb and the maximum value is 32Mb.

####性能参数

参数名称和默认值含义
-XX:+AggressiveOptsTurn on point performance compiler optimizations that are expected to be default in upcoming releases. (Introduced in 5.0 update 6.)
-XX:CompileThreshold=10000Number of method invocations/branches before compiling [-client: 1,500]
-XX:LargePageSizeInBytes=4mSets the large page size used for the Java heap. (Introduced in 1.4.0 update 1.) amd64: 2m.
-XX:MaxHeapFreeRatio=70Maximum percentage of heap free after GC to avoid shrinking.(堆最大空闲百分比,大于这个值堆会自动收缩)
-XX:MaxNewSize=sizeMaximum size of new generation (in bytes). Since 1.4, MaxNewSize is computed as a function of NewRatio. [1.3.1 Sparc: 32m; 1.3.1 x86: 2.5m.]
-XX:MaxPermSize=64mSize of the Permanent Generation. [5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.]
-XX:MinHeapFreeRatio=40Minimum percentage of heap free after GC to avoid expansion.(堆最小空闲百分比)
-XX:NewRatio=2Ratio of old/new generation sizes. [Sparc -client: 8; x86 -server: 8; x86 -client: 12.]-client: 4 (1.3) 8 (1.3.1+), x86: 12]
-XX:NewSize=2mDefault size of new generation (in bytes) [5.0 and newer: 64 bit VMs are scaled 30% larger; x86: 1m; x86, 5.0 and older: 640k]
-XX:ReservedCodeCacheSize=32m?-- Reserved code cache size (in bytes) - maximum code cache size. [Solaris 64-bit, amd64, and -server x86: 2048m; in 1.5.0_06 and earlier, Solaris 64-bit and amd64: 1024m.](设置代码缓存)
-XX:SurvivorRatio=8Ratio of eden/survivor space size [Solaris amd64: 6; Sparc in 1.3.1: 25; other Solaris platforms in 5.0 and earlier: 32]
-XX:TargetSurvivorRatio=50?-- Desired percentage of survivor space used after scavenge.(清理之后,希望生还者区使用的百分比。)
-XX:ThreadStackSize=512Thread Stack Size (in Kbytes). (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
-XX:+UseBiasedLocking?-- Enable biased locking. For more details, see this tuning example. (Introduced in 5.0 update 6.) 5.0: false
-XX:+UseFastAccessorMethodsUse optimized versions of GetField.(使用优化版本的基本类型get方法)
-XX:-UseISMUse Intimate Shared Memory. [Not accepted for non-Solaris platforms.] For details, see Intimate Shared Memory.
-XX:+UseLargePages?-- Use large page memory. (Introduced in 5.0 update 5.) For details, see Java Support for Large Memory Pages.(启用大内存分页)
-XX:+UseMPSSUse Multiple Page Size Support w/4mb pages for the heap. Do not use with ISM as this replaces the need for ISM. (Introduced in 1.4.0 update 1, Relevant to Solaris 9 and newer.) [1.4.1 and earlier: false]
-XX:+UseStringCache?-- Enables caching of commonly allocated strings.
-XX:AllocatePrefetchLines=1Number of cache lines to load after the last object allocation using prefetch instructions generated in JIT compiled code. Default values are 1 if the last allocated object was an instance and 3 if it was an array.
-XX:AllocatePrefetchStyle=1?-- Generated code style for prefetch instructions. 0 - no prefetch instructions are generated, 1 - execute prefetch instructions after each allocation,2 - use TLAB allocation watermark pointer to gate when prefetch instructions are executed.
-XX:+UseCompressedStrings?-- Use a byte[] for Strings which can be represented as pure ASCII. (Introduced in Java 6 Update 21 Performance Release)
-XX:+OptimizeStringConcat?-- Optimize String concatenation operations where possible. (Introduced in Java 6 Update 20)
调试参数
参数名称和默认值含义
-XX:-CITimePrints time spent in JIT Compiler. (Introduced in 1.4.0.)
-XX:ErrorFile=./hs_err_pid.logIf an error occurs, save the error data to this file. (Introduced in 6.)
-XX:-ExtendedDTraceProbesEnable performance-impacting dtrace probes. (Introduced in 6. Relevant to Solaris only.)
-XX:HeapDumpPath=./java_pid.hprof?–Path to directory or filename for heap dump. Manageable. (Introduced in 1.4.2 update 12, 5.0 update 7.)(堆转储文件的路径或文件名)
-XX:-HeapDumpOnOutOfMemoryErrorDump heap to file when java.lang.OutOfMemoryError is thrown. Manageable. (Introduced in 1.4.2 update 12, 5.0 update 7.)
-XX:OnError=";"Run user-defined commands on fatal error. (Introduced in 1.4.2 update 9.)
-XX:OnOutOfMemoryError=";"?–Run user-defined commands when an OutOfMemoryError is first thrown. (Introduced in 1.4.2 update 12, 6)
-XX:-PrintClassHistogram?–Print a histogram(柱状图) of class instances on Ctrl-Break. Manageable. (Introduced in 1.4.2.) The jmap -histo command provides equivalent functionality.
-XX:-PrintConcurrentLocks?–Print java.util.concurrent locks in Ctrl-Break thread dump. Manageable. (Introduced in 6.) The jstack -l command provides equivalent functionality.
-XX:-PrintCommandLineFlags?–Print flags that appeared on the command line. (Introduced in 5.0.)
-XX:-PrintCompilationPrint message when a method is compiled.
-XX:-PrintGCPrint messages at garbage collection. Manageable.
-XX:-PrintGCDetailsPrint more details at garbage collection. Manageable. (Introduced in 1.4.0.)
-XX:-PrintGCTimeStampsPrint timestamps at garbage collection. Manageable (Introduced in 1.4.0.)
-XX:-PrintTenuringDistributionPrint tenuring age information.(打印年龄信息)
-XX:-PrintAdaptiveSizePolicyEnables printing of information about adaptive generation sizing.
-XX:-TraceClassLoadingTrace loading of classes.(打印类加载)
-XX:-TraceClassLoadingPreorderTrace all classes loaded in order referenced (not loaded). (Introduced in 1.4.2.)(按照引用顺序打印所有类加载。)
-XX:-TraceClassResolutionTrace constant pool resolutions. (Introduced in 1.4.2.)(打印常量池Trace constant pool resolutions. )
-XX:-TraceClassUnloadingTrace unloading of classes.(打印卸载类)
-XX:-TraceLoaderConstraintsTrace recording of loader constraints. (Introduced in 6.)
-XX:+PerfDataSaveToFileSaves jvmstat binary data on exit.
-XX:ParallelGCThreads=nSets the number of garbage collection threads in the young and old parallel garbage collectors. The default value varies with the platform on which the JVM is running.
-XX:+UseCompressedOopsEnables the use of compressed pointers (object references represented as 32 bit offsets instead of 64-bit pointers) for optimized 64-bit performance with Java heap sizes less than 32gb.
-XX:+AlwaysPreTouch?–Pre-touch the Java heap during JVM initialization. Every page of the heap is thus demand-zeroed during initialization rather than incrementally during application execution.(当JVM初始化时预先对Java堆进行预先摸底(Pre-touch),堆的每个页初始化时满足需求,而不是应用执行时递增。)
-XX:AllocatePrefetchDistance=n?–Sets the prefetch distance for object allocation. Memory about to be written with the value of new objects is prefetched into cache at this distance (in bytes) beyond the address of the last allocated object. Each Java thread has its own allocation point. The default value varies with the platform on which the JVM is running.
-XX:InlineSmallCode=n?–Inline a previously compiled method only if its generated native code size is less than this. The default value varies with the platform on which the JVM is running.
-XX:MaxInlineSize=35?–Maximum bytecode size of a method to be inlined.
-XX:FreqInlineSize=nMaximum bytecode size of a frequently executed method to be inlined. The default value varies with the platform on which the JVM is running.
-XX:LoopUnrollLimit=nUnroll loop bodies with server compiler intermediate representation node count less than this value. The limit used by the server compiler is a function of this value, not the actual value. The default value varies with the platform on which the JVM is running.
-XX:InitialTenuringThreshold=7Sets the initial tenuring threshold for use in adaptive GC sizing in the parallel young collector. The tenuring threshold is the number of times an object survives a young collection before being promoted to the old, or tenured, generation.
-XX:MaxTenuringThreshold=nSets the maximum tenuring threshold for use in adaptive GC sizing. The current largest value is 15. The default value is 15 for the parallel collector and is 4 for CMS.
-Xloggc:Log GC verbose output to specified file. The verbose output is controlled by the normal verbose GC flags.(指定GC文件)
-XX:-UseGCLogFileRotationEnabled GC log rotation, requires -Xloggc.(开启日志分割)
-XX:NumberOfGClogFiles=1Set the number of files to use when rotating logs, must be >= 1. The rotated log files will use the following naming scheme, .0, .1, …, .n-1.
-XX:GCLogFileSize=8KThe size of the log file at which point the log will be rotated, must be >= 8K.

GC性能方面的考虑
对于GC的性能主要有2个方面的指标:吞吐量throughput(工作时间不算gc的时间占总的时间比)和暂停pause(gc发生时app对外显示的无法响应)。

  • Total Heap
    默认情况下,vm会增加/减少heap大小以维持free space在整个vm中占的比例,这个比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。
    一般而言,server端的app会有以下规则:

    • 对vm分配尽可能多的memory(分配过大内存可能会在jvm进行老年代GC时花费很长时间,造型系统停留)
    • 将Xms和Xmx设为一样的值。如果虚拟机启动时设置使用的内存比较小,这个时候又需要初始化很多对象,虚拟机就必须重复地增加内存。
    • 处理器核数增加,内存也跟着增大。
  • The Young Generation
    另外一个对于app流畅性运行影响的因素是young generation的大小。young generation越大,minor collection越少;但是在固定heap size情况下,更大的young generation就意味着小的tenured generation,就意味着更多的major collection(major collection会引发minor collection)。
    NewRatio反映的是young和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,将这两个值设为一样就固定了young generation的大小(同Xms和Xmx设为一样)。
    如果希望,SurvivorRatio也可以优化survivor的大小,不过这对于性能的影响不是很大。SurvivorRatio是eden和survior大小比例。
    一般而言,server端的app会有以下规则:

  • 首先决定能分配给vm的最大的heap size,然后设定最佳的young generation的大小;

  • 如果heap size固定后,增加young generation的大小意味着减小tenured generation大小。让tenured generation在任何时候够大,能够容纳所有live的data(留10%-20%的空余)。

经验&&规则

  1. 年轻代大小选择
    - 响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择).在此种情况下,年轻代收集 发生的频率也是最小的.同时,减少到达年老代的对象.
    - 吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度.因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用
    避免设置过小.当新生代设置过小时会导致:1.YGC次数更加频繁 2.可能导致YGC对象直接进入旧生代,如果此时旧生代满了,会触发FGC
  2. 年老代大小选择
    响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数.如果堆设置小了,可以会造成内存碎 片,高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间.最优化的方案,一般需要参考以下数据获得:
    并发垃圾收集信息、持久代并发收集次数、传统GC信息、花在年轻代和年老代回收上的时间比例。
    吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代.原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象.
  3. 较小堆引起的碎片问题
    因为年老代的并发收集器使用标记,清除算法,所以不会对堆进行压缩.当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.但是,当堆空间较小时,运行一段时间以后,就会出现"碎片",如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记,清除方式进行回收.如果出现"碎片",可能需要进行如下配置:
    -XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩.
    -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩
  4. 用64位操作系统,Linux下64位的jdk比32位jdk要慢一些,但是吃得内存更多,吞吐量更大
  5. XMX和XMS设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力
  6. 使用CMS的好处是用尽量少的新生代,经验值是128M-256M, 然后老生代利用CMS并行收集, 这样能保证系统低延迟的吞吐效率。 实际上cms的收集停顿时间非常的短,2G的内存, 大约20-80ms的应用程序停顿时间
  7. 系统停顿的时候可能是GC的问题也可能是程序的问题,多用jmap和jstack查看,或者killall -3 java,然后查看java控制台日志,能看出很多问题。(相关工具的使用方法将在后面的blog中介绍)
  8. 仔细了解自己的应用,如果用了缓存,那么年老代应该大一些,缓存的HashMap不应该无限制长,建议采用LRU算法的Map做缓存,LRUMap的最大长度也要根据实际情况设定。
  9. 采用并发回收时,年轻代小一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不会影响其他程序继续运行,网站不会停顿
  10. JVM参数的设置(特别是 –Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等参数的设置没有一个固定的公式,需要根据PV old区实际数据 YGC次数等多方面来衡量。为了避免promotion faild可能会导致xmn设置偏小,也意味着YGC的次数会增多,处理并发访问的能力下降等问题。每个参数的调整都需要经过详细的性能测试,才能找到特定应用的最佳配置。

promotion failed:

垃圾回收时promotion failed是个很头痛的问题,一般可能是两种原因产生,第一个原因是救助空间不够,救助空间里的对象还不应该被移动到年老代,但年轻代又有很多对象需要放入救助空间;第二个原因是年老代没有足够的空间接纳来自年轻代的对象;这两种情况都会转向Full GC,网站停顿时间较长。

解决方方案一:

第一个原因我的最终解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,第二个原因我的解决办法是设置CMSInitiatingOccupancyFraction为某个值(假设70),这样年老代空间到70%时就开始执行CMS,年老代有足够的空间接纳来自年轻代的对象。

解决方案一的改进方案:

又有改进了,上面方法不太好,因为没有用到救助空间,所以年老代容易满,CMS执行会比较频繁。我改善了一下,还是用救助空间,但是把救助空间加大,这样也不会有promotion failed。具体操作上,32位Linux和64位Linux好像不一样,64位系统似乎只要配置MaxTenuringThreshold参数,CMS还是有暂停。为了解决暂停问题和promotion failed问题,最后我设置-XX:SurvivorRatio=1 ,并把MaxTenuringThreshold去掉,这样即没有暂停又不会有promotoin failed,而且更重要的是,年老代和永久代上升非常慢(因为好多对象到不了年老代就被回收了),所以CMS执行频率非常低,好几个小时才执行一次,这样,服务器都不用重启了。

JVM之参数分配(全面讲解)
Java内存泄露及性能调优实例

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值