首页 文章 精选 留言 我的

精选列表

搜索[作者要求],共10000篇文章
优秀的个人博客,低调大师

🏆「作者推荐」Java技术专题-JVM研究系列(49)JVM分析与调优技巧分析(原理篇)

JVM空间说明 在JDK1.7及以前,HotSpot虚拟机将java类信息、常量池、静态变量、即时编译器编译后的代码等数据,存储在Perm(永久带)里(对于其他虚拟机如BEA JRockit、IBM J9等是不存在永久带概念的),类的元数据和静态变量在类加载的时候被分配到Perm里,当常量池回收或者类被卸载的时候,垃圾收集器会回收这一部分内存,但效果不太理想。 JDK1.8时,HotSpot虚拟机对JVM模型进行了改造,将类元数据放到了本地内存中,将常量池和静态变量放到了Java堆里,HotSpot VM将会为类的元数据明确的分配与释放本地内存,在这种架构下,类元数据就突破了-XX:MaxPermSize的限制,所以此配置已经失效,现在可以使用更多的本地内存。这样一定程度上解决了原来在运行时生成大量的类,从而经常Full GC的问题——如运行时使用反射、代理等。 干货要点 可以发现最明显的一个变化是元空间从虚拟机转移到了本地内存。默认情况下,元数据空间大小仅受限于本地内存,这意味着以后不会因为永久代大小不够而抛出OOM异常了。 jdk1.8以前,HotSpot VM将class和类的jar包数据存储在PermGen里, PermGen大小是固定的,而且项目之间无法公用公有的class,所以很容易碰到OOM异常。改成MetaSpace后。 各个项目会共享同样的class空间。比如多个项目都引用了apache-common包,在MetaSpace中只会存储一份的apache-common的class,提高了内存的利用率,垃圾回收更有效。 Minor GC—复制算法具体过程: 将Eden和S0中还存活着的对象一次性的复制到S1中,并且清理掉Eden与S0的空间。如果S1放不下还存活着的对象,那这些对象将通过分配担保机制进入老年代。【原理上随时保持S0和S1有一个是空的,用来存下一次的对象】 Eden区快满的时候,会进行上一步类似操作,将Eden和S1区的年纪大的对象放到S0区【此时S1区就是空的】 直到Eden区快满,S0或者S1也快满的时候,这时候就把这两个区的年纪大的对象放到Old区。 依次循环,直到Old区也快满的时候,Eden区也快满的时候,会对整个这一块内存区域进行一次大清洗(FullGC),腾出内存,为之后的对象创建,程序运行腾地方。 新生代GC(Minor GC):指发生在新生代的垃圾回收动作,因为java对象大多具备朝生夕灭的特征,所以Minor GC发生的特别频繁,一般回收速度也很快。 老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,至少会伴随一次的MinorGC(但非绝对,在Parallel Scavenge收集器的收集策略里就有直接进行Minor GC的策略选择过程)。 Major GC的速度一般比Minor GC慢10倍以上。 升级JDK1.8之后,上面的perm配置已经变成 -XX:MetaspaceSize=512M XX:MaxMetaspaceSize=1024M MetaspaceSize如果不做配置,通过jinfo查看默认MetaspaceSize大小(约21M),MaxMetaspaceSize很大很大,前面说过MetaSpace只受本地内存大小限制。 结果为:-XX:MetaspaceSize=21807104 jinfo -flag MetaspaceSize 1234 结果为:-XX:MaxMetaspaceSize=18446744073709547520 jinfo -flag MaxMetaspaceSize 1234 干货: MetaspaceSize为触发FullGC的阈值,默认约为21M,如做了配置,最小阈值为自定义配置大小。空间使用达到阈值,触发FullGC,同时对该值扩大。当然如果元空间实际使用小于阈值,在GC的时候也会对该值缩小。 MaxMetaspaceSize为元空间的最大值,如果设置太小,可能会导致频繁FullGC,甚至OOM。 -XX 参数被称为不稳定参数,之所以这么叫是因为此类参数的设置很容易引起JVM 性能上的差异,使JVM 存在极大的不稳定性。如果此类参数设置合理将大大提高JVM 的性能及稳定性。 不稳定参数语法规则: 布尔类型参数值 -XX:+ '+'表示启用该选项 -XX:- '-'表示关闭该选项 数字类型参数值: -XX:= 给选项设置一个数字类型值,可跟随单位,例如:'m’或’M’表示兆字节;'k’或’K’千字节;'g’或’G’千兆字节。32K与32768是相同大小的。 字符串类型参数值: -XX:= 给选项设置一个字符串类型值,通常用于指定一个文件、路径或一系列命令列表。 -XX:HeapDumpPath=./dump.core JVM参数示例 -Xmx4g –Xms4g –Xmn1200m –Xss512k -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:PermSize=100m -XX:MaxPermSize=256m -XX:MaxTenuringThreshold=15 解析: -Xmx4g:堆内存最大值为4GB。 -Xms4g:初始化堆内存大小为4GB 。 -Xmn1200m:设置年轻代大小为1200MB。增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 -Xss512k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1MB,以前每个线程堆栈大小为256K。应根据应用线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。 -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 -XX:SurvivorRatio=8:设置年轻代中Eden区与Survivor区的大小比值。设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10 -XX:PermSize=100m:初始化永久代大小为100MB。 -XX:MaxPermSize=256m:设置持久代大小为256MB。 -XX:MaxTenuringThreshold=15:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。 JVM调优目标 何时需要做jvm调优? heap 内存(老年代)持续上涨达到设置的最大内存值; Full GC 次数频繁; GC 停顿时间过长(超过1秒); 应用出现OutOfMemory 等内存异常; 应用中有使用本地缓存且占用大量内存空间; 系统吞吐量与响应性能不高或下降。 JVM调优原则 多数的Java应用不需要在服务器上进行JVM优化; 多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题; 在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合); 减少创建对象的数量; 减少使用全局变量和大对象; JVM优化是到最后不得已才采用的手段; 在实际使用中,分析GC情况优化代码比优化JVM参数更好; JVM调优目标 GC低停顿; GC低频率; 低内存占用; 高吞吐量; JVM调优量化目标(示例): Heap 内存使用率 <= 70%; Old generation内存使用率<= 70%; avgpause <= 1秒; Full gc 次数0 或 avg pause interval >= 24小时 ; 注意:不同应用,其JVM调优量化目标是不一样的。 JVM调优经验 JVM调优经验总结 JVM调优的一般步骤为: 第1步:分析GC日志及dump文件,判断是否需要优化,确定瓶颈问题点; 第2步:确定JVM调优量化目标; 第3步:确定JVM调优参数(根据历史JVM参数来调整); 第4步:调优一台服务器,对比观察调优前后的差异; 第5步:不断的分析和调整,直到找到合适的JVM参数配置; 第6步:找到最合适的参数,将这些参数应用到所有服务器,并进行后续跟踪。 JVM调优重要参数解析 注意:不同应用,其JVM最佳稳定参数配置是不一样的。 配置: -server -Xms12g -Xmx12g -XX:PermSize=500m -XX:MaxPermSize=1000m -Xmn2400m -XX:SurvivorRatio=1 -Xss512k -XX:MaxDirectMemorySize=1G -XX:+DisableExplicitGC -XX:CompileThreshold=8000 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCompressedOops -XX:CMSInitiatingOccupancyFraction=60 -XX:ConcGCThreads=4 -XX:MaxTenuringThreshold=10 -XX:ParallelGCThreads=8 -XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:CMSMaxAbortablePrecleanTime=500 -XX:CMSFullGCsBeforeCompaction=4 XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection -XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/weblogic/gc/gc_$$.log 重要参数(可调优)解析: -Xms12g:初始化堆内存大小为12GB。 -Xmx12g:堆内存最大值为12GB 。 -Xmn2400m:新生代大小为2400MB,包括 Eden区与2个Survivor区。 -XX:SurvivorRatio=1:Eden区与一个Survivor区比值为1:1。 -XX:MaxDirectMemorySize=1G:直接内存。报java.lang.OutOfMemoryError: Direct buffer memory 异常可以上调这个值。 -XX:+DisableExplicitGC:禁止运行期显式地调用 System.gc() 来触发fulll GC。 注意: Java RMI的定时GC触发机制可通过配置-Dsun.rmi.dgc.server.gcInterval=86400来控制触发的时间。 -XX:CMSInitiatingOccupancyFraction=60:老年代内存回收阈值,默认值为68。 -XX:ConcGCThreads=4:CMS垃圾回收器并行线程线,推荐值为CPU核心数。 -XX:ParallelGCThreads=8:新生代并行收集器的线程数。 -XX:MaxTenuringThreshold=10:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。 -XX:CMSFullGCsBeforeCompaction=4:指定进行多少次fullGC之后,进行tenured区 内存空间压缩。 -XX:CMSMaxAbortablePrecleanTime=500:当abortable-preclean预清理阶段执行达到这个时间时就会结束。 触发Full GC的场景及应对策略 年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC,对老年代GC称为MajorGC,而Full GC是对整个堆来说的,在最近几个版本的JDK里默认包括了对永生带即方法区的回收(JDK8中无永生带了),出现Full GC的时候经常伴随至少一次的Minor GC,但非绝对的。MajorGC的速度一般会比Minor GC慢10倍以上。 触发Full GC的场景及应对策略: System.gc()方法的调用,应对策略:通过-XX:+DisableExplicitGC来禁止调用System.gc ; 老年代代空间不足,应对策略:让对象在Minor GC阶段被回收,让对象在新生代多存活一段时间,不要创建过大的对象及数组; 永生区空间不足,应对策略:增大PermGen空间 GC时出现promotionfailed和concurrent mode failure,应对策略:增大survivor space Minor GC后晋升到旧生代的对象大小大于老年代的剩余空间,应对策略:增大Tenured space 或下调CMSInitiatingOccupancyFraction=60 内存持续增涨达到上限导致Full GC ,应对策略:通过dumpheap 分析是否存在内存泄漏 Gc日志分析工具 借助GCViewer日志分析工具,可以非常直观地分析出待调优点。 可从以下几方面来分析: Memory,分析Totalheap、Tenuredheap、Youngheap内存占用率及其他指标,理论上内存占用率越小越好; Pause ,分析Gc pause、Fullgc pause、Total pause三个大项中各指标,理论上GC次数越少越好,GC时长越小越好;

优秀的个人博客,低调大师

突破百度网盘限速工具Pandownload作者被抓,存在泄露用户隐私数据风险

今年2月,受害人刘某报案称其下载的“Pandownload”软件会在未授权的情况下,将自己百度网盘的数据共享出去,导致隐私照片和文件泄露。宝应县局网安民警立即开展案情分析研判,研习法律条文,解剖软件结构。面对满屏的数据,一盯就是几个小时。 经过梳理,警方发现该软件可以以非会员权限突破百度网盘官方设定,实现高速下载,系侵入、非法控制计算机信息系统的程序、工具,并且该软件的使用者达到数万人,致使北京百度网讯科技有限公司(“百度公司”)损失高达上千万元。 4月初,在掌握了充分证据后,宝应网安远赴广东,抓捕犯罪嫌疑人蔡某萌,当场查获电脑、手机等作案工具。 经查:2017年,犯罪嫌疑人在家中编写可以通过百度网盘官方服务器的客户端身份认证,实现以非会员权限突破百度网盘官方设定,高速下载“Pandownload”软件,并在互联网上发布。期间犯罪嫌疑人租用网络服务器进行更新维护并发布接受捐赠的收款码,同时建立QQ群,向进群人员收取1至10元不等的进群费,群内提供更稳定的“Pandownload”内测版本。截至案发,犯罪嫌疑人非法获利30万余元。

优秀的个人博客,低调大师

2020年薪30W的Java程序员都要求熟悉JVM与性能调优!

前言 作为Java程序员,你有没有被JVM伤害过?面试的时候是否碰到过对JVM的灵魂拷问? 一、JVM 内存区域划分 1.程序计数器(线程私有)程序计数器(Program Counter Register),也有称作为 PC 寄存器。保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当 CPU 需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加 1 或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。也就是说是用来指示执行哪条指令的。由于在 JVM 中,多线程是通过线程轮流切换来获得 CPU 执行时间的,因此,在任一具体时刻,一个 CPU 的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,否则就会影响到程序的正常执行次序。因此,可以这么说,程序计数器是每个线程所私有的。在 JVM 规范中规定,如果线程执行的是非 native 方法,则程序计数器中保存的是当前需要执行的指令的地址;如果线程执行的是 native 方法,则程序计数器中的值是 undefined。由于程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,因此,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的。异常情况:不存在2.Java 栈(线程私有)3.本地方法栈(线程私有)4.堆(线程共享)5.方法区(线程共享)6.直接内存(线程共享) 二、JVM 执行子系统 1.Class 类文件结构1.1 Java 跨平台的基础各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石,也是语言无关性的基础。Java 虚拟机不和包括 Java 在内的任何语言绑定,它只与“Class 文件”这种特定的二进制文件格式所关联,Class 文件中包含了 Java虚拟机指令集和符号表以及若干其他辅助信息。1.2 Class 类的本质任何一个 Class 文件都对应着唯一一个类或接口的定义信息,但反过来说,Class 文件实际上它并不一定以磁盘文件的形式存在。Class 文件是一组以 8 位字节为基础单位的二进制流。1.3 Class 文件格式各个数据项目严格按照顺序紧凑地排列在 Class 文件之中,中间没有添加任何分隔符,这使得整个 Class 文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。Class 文件格式采用一种类似于 C 语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。无符号数属于基本的数据类型,以 u1、u2、u4、u8 来分别代表 1 个字节、2 个字节、4 个字节和 8 个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照 UTF-8编码构成字符串值。表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个 Class 文件本质上就是一张表。2.字节码指令2.1 加载和存储指令2.2 运算或算术指令2.3 类型转换指令2.4 创建类实例的指令2.5 创建数组的指令2.6 访问字段指令2.7 数组存取相关指令2.8 检查类实例类型的指令2.9 操作数栈管理指令2.10 控制转移指令2.11 方法调用指令 2.12 方法返回指令2.13 异常处理指令2.14 同步指令3.类加载机制4.类加载器4.1 系统的类加载器4.2 双亲委派模型5.Tomcat 类加载机制6.方法调用详解6.1 解析6.2 静态分派6.3 动态分派6.4 基于栈的字节码解释执行引擎 三.垃圾回收器和内存分配策略 1.Java 中是值传递还是引用传递?2.引用类型3.基本垃圾回收算法3.1.1 引用计数(Reference Counting):比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为 0 的对象。此算法最致命的是无法处理循环引用的问题。3.1.2 可达性分析清理 标记-清除(Mark-Sweep):此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。 复制(Copying): 此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。 标记-整理(Mark-Compact):此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,清除标记对象,并未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。3.1 按照基本回收策略分3.2 按分区对待的方式分3.3 按系统线程分4.分代处理垃圾5.JAVA 中垃圾回收 GC 的类型 四、编写高效优雅 Java 程序 1.面向对象1.1 构造器参数太多怎么办?用 builder 模式,用在(1)5 个或者 5 个以上的成员变量(2)参数不多,但是在未来,参数会增加Builder 模式:属于对象的创建模式,一般有(1)抽象建造者:一般来说是个接口,包含1)建造方法,建造部件的方法(不止一个)2)返回产品的方法(2) 具体建造者(3) 导演者,调用具体的建造者,创建产品对象(4)产品,需要建造的复杂对象对于客户端,创建导演者和具体建造者,并把具体建造者交给导演者,然后由客户端通知导演者操纵建造者进行产品的创建。在实际的应用过程中,有时会省略抽象建造者和导演者。1.2 不需要实例化的类应该构造器私有1.3 不要创建不必要的对象1.4 避免使用终结方法1.5 使类和成员的可访问性最小化1.6 使可变性最小化1.7 复合优先于继承1.8 接口优于抽象类2.方法2.1 可变参数要谨慎使用2.2 返回零长度的数组或集合,不要返回 null2.3 优先使用标准的异常3.通用程序设计 五、性能优化 一个 web 应用不是一个孤立的个体,它是一个系统的部分,系统中的每一部分都会影响整个系统的性能1.常用的性能评价/测试指标1.1 响应时间提交请求和返回该请求的响应之间使用的时间,一般比较关注平均响应时间。常用操作的响应时间列表: 1.2 并发数同一时刻,对服务器有实际交互的请求数。和网站在线用户数的关联:1000 个同时在线用户数,可以估计并发数在 5%到 15%之间,也就是同时并发数在 50~150 之间。1.3 吞吐量对单位时间内完成的工作量(请求)的量度1.4 关系系统吞吐量和系统并发数以及响应时间的关系:理解为高速公路的通行状况:吞吐量是每天通过收费站的车辆数目(可以换算成收费站收取的高速费),并发数是高速公路上的正在行驶的车辆数目,响应时间是车速。车辆很少时,车速很快。但是收到的高速费也相应较少;随着高速公路上车辆数目的增多,车速略受影响,但是收到的高速费增加很快;随着车辆的继续增加,车速变得越来越慢,高速公路越来越堵,收费不增反降;如果车流量继续增加,超过某个极限后,任务偶然因素都会导致高速全部瘫痪,车走不动,当然后也收不着,而高速公路成了停车场(资源耗尽)。2.常用的性能优化手段2.1 避免过早优化2.2 进行系统性能测试2.3 寻找系统瓶颈,分而治之,逐步优化2.4 前端优化常用手段 3 应用服务性能优化3.1 缓存3.1.1 缓存的基本原理和本质3.1.2 合理使用缓冲的准则3.1.3 分布式缓存与一致性哈希3.2 异步3.2.1 同步和异步,阻塞和非阻塞3.2.2 常见异步的手段3.3 集群 3.4 应用相关3.4.1 代码级别3.4.2 并发编程3.4.3 资源的复用3.4.4 JVM3.4.5 GC 调优3.4.6 调优实战3.4.7 存储性能优化 上面的这些问题只是给大家一个借鉴作用,最主要的是给自己增加知识的储备,有备无患。关于JVM与性能调优总结了将近50页pdf文档,欢迎关注我的公种浩:程序员追风,获取这些整理的资料! 希望能帮助到你面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。 最后 欢迎大家一起交流,喜欢文章记得关注我点个赞哟,感谢支持!

优秀的个人博客,低调大师

CyberX推出ICS攻击向量预测服务 进行工控安全演练 满足Gartner自适应安全架构要求

上周四,工业网络安全与威胁情报公司CyberX宣布推出ICS攻击向量预测技术,这是一种模拟技术,可以对当前工控环境中的漏洞及资产进行高级分析,并能够可视化的模拟攻击形式及路径,进而预演各种缓解措施的效果,组织可利用这种技术,更有效而熟练地利用有限资源和狭窄的维护时间窗口。 工控安全ICS攻击向量预测技术 CyberX公司将这种新型的工业控制系统(ICS)安全服务命名为“ICS攻击向量预测”。基于公司专有的分析技术,该服务可持续预测潜在的攻击位置,帮助组织预防攻击。 方案可针对运营技术(OT)网络中关键资产的所有潜在攻击链进行直观展示,并根据风险级别对攻击场景进行排序,安全团队可依此确定处理风险的先后次序。 网络安全人员可获得每个漏洞的详细缓解建议,包括为Windows设备打补丁、升级有漏洞的PLC固件、停用不必要或不受控的远程访问方法

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册