我可以做什么来使 jar/class 更小?
我正在开发一个Java Applet,减少二进制代码的大小将使Applet打开速度更快,并改善用户体验。
我可以做些什么来减少类和/或 jar 文件的大小?我想确保我没有错过明显的技巧。
我知道在 C++ 世界中,诸如剥离调试符号之类的编译器选项可以产生巨大的差异,但我从未见过 Java 中的类似选项。
I'm developing a Java Applet, and reducing the size of the binary code will make the applet open faster and will improve the user experience.
Is there anything I can do to reduce the size of classes and / or jar files? I want to be sure I'm not missing obvious tricks.
I know that in the C++ world compiler options for e.g. stripping debug symbols can make a huge difference, but I've never seen something like that for Java.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您可以使用
它来删除调试信息 - 我不知道它可能会产生多大的差异。
您有多确信下载时间是瓶颈?小程序有多大?除非它很大,否则我怀疑下载后大小会产生很大的影响。
You can use
to remove debugging information - I don't know how much difference it's likely to make though.
How convinced are you that the download time is the bottleneck? How big is the applet? Unless it's enormous, I doubt that size will make much difference after it's downloaded.
查看此页面,了解有关如何缩小 jar 文件的一些提示 - http:// /wiki.java.net/bin/view/Games/4KGamesDesign 。尽管有些可能不适用,因为您没有尝试绝对最小化,但您可以应用一些通用技巧,而不会影响代码质量。
但这里有一个总结:
将代码缩减为一个类。每个类都会在 JAR 文件中添加一个条目的开销,以及一个全新的常量池和类列表。
将你的方法保持在最低限度。每个方法都会增加类文件的开销。您所需要的只是一个
main()
方法,以及实现键盘和/或鼠标例程的方法。不要使用全局变量。全局变量需要类中特殊的元数据来识别。然而,方法局部变量只是堆栈条目,使用起来不需要任何额外费用。
使用 7Zip 或 KZip 等优秀压缩器来创建 JAR 文件。 JAR 实用程序主要是为了正确性而不是压缩率而设计的。
使用 ProGuard、JoGa 或 JShrink 等混淆器来优化类的大小。
使用单个字符作为类文件名。这会减少其内部大小,减少 Zip 程序存储的信息量,并减少清单的大小。
参考尽可能少的类。您引用的每个类都会添加完整的包和类名称,以及您正在调用的方法签名。
冗余(例如对所有方法、类和字段使用相同的名称)可以提高压缩率。
私有方法和最终方法可以由类优化器内联。
使用
String.valueOf()
方法将基元转换为字符串。例如,""+number
扩展为:new StringBuffer?().append("").append(number).toString()
浪费大量空间在新的类和方法引用中。源代码中使用的静态字符串、浮点数和整数存储在常量池中。因此,您可以越多地重用静态值,
你的班级会更小。
您可以自由地使用静态最终变量作为常量。这将使您的代码更具可读性,并且 ProGuard 会对其进行优化,因此不会产生额外的开销。
check out this page for some tips on how you could make your jar files smaller - http://wiki.java.net/bin/view/Games/4KGamesDesign . Even though some may not apply since you are not trying for absolute minimalization, there are some general tips that you can apply without compromising code quality.
but a summary here:
Keep your code down to one class. Each class adds the overhead of an entry in the JAR file, as well as a brand new constant pool and class list.
Keep your methods to a minimum. Each method adds overhead in the class file. All you should need is a
main()
method, and methods to implement the keyboard and/or mouse routines.Don't use global variables. Global variables require special meta-data in the class to identify. Method-local variables, however, are only stack entries and cost nothing extra to use.
Use a good compressor like 7Zip or KZip to create your JAR files. The JAR utility is mostly designed for correctness, not compression ratios.
Use an obfuscator like ProGuard, JoGa, or JShrink to optimize the size of your class.
Use a single character for the class file name. This reduces its size internally, reduces the amount of info the Zip program stores, and reduces the size of the manifest.
Reference as few classes as possible. Each class you reference adds the full package and class name, plus the method signature you're calling.
Redundancy (such as using the same name for all your methods and classes and fields) improves compression ratios.
Methods made private and final can be inlined by a class optimizer.
Use the
String.valueOf()
method to convert primitives to strings. For example,""+number
expands to:new StringBuffer?().append("").append(number).toString()
wasting a great deal of space in new class and method references.Static strings, floats, and integers used in the source code get stored in the constant pool. As a result, the more you can reuse a static value, the
smaller your class will be.
You can make liberal use of static final variables for constants. This will make your code more readable and ProGuard will optimize this away so there is no extra overhead.
proguard 网站上的报告显示了减少的示例,范围从 19% 到 90%。
Reports on the proguard site show examples of the reduction, ranging from 19 to 90%.
Classdepandjar 在 Jini 世界中用于减少 jar 文件大小(Jini 附带了大量远程代码) ,因此有此要求)。它会删除同一 jar 中未引用的类。
显然,也有例外(按名称加载的类等),因此您可以在配置中容纳这些例外。您很可能应该针对您的“摇动”jar 进行测试,以确定相关依赖项是否仍然存在。
Classdepandjar is used in the Jini world to reduce jar file sizes (Jini ships around a lot of remote code, hence this requirement). It removes classes that aren't referenced from within that same jar.
Obviously there are exceptions to this (classes loaded by name etc.) and so you can accommodate these in the config. You should most likely test against your 'shaken down' jar to determine that relevant dependencies remain.
一些改进小程序大小的建议:
混淆 - Proguard 是最好的对于我来说,整体性能下降了 25% 以上。此外,它将在 Jar 期间提供良好的压缩。
优化任何资源 - 使用图像优化器减少附加图像,如果适用,降低质量。
优化
代码更改 - 我发现您并不是真的想这样做,但值得查看一下您的 Jar 文件并检查生成了多少个类。最简单的类将花费大约 500 字节。如果您有很多匿名内部类,则可能值得重构。
根据需要加载资源 - 加载初始小程序。启动后异步加载其他资源。
Some suggestions to improve applet size:
Obfuscate - Proguard was the best for overall performance for me - over 25% reduction for me. In addition it will provide decent compression during the Jar.
Optimize any resources - reduce attached images using image optimizers, lower quality if appropriate.
Code changes - I see that you don't really want to do this, but it's worth taking a look at your Jar files and checking how many classes are produced. The most trivial class will cost about 500 bytes. If you have lots of anonymous inner classes it may be worth refactoring.
Load resources as required - Load the initial applet. Load additional resources asynchronously after starting.
pack200 (和 gzip )生成的文件比 jar 小得多(实际上是 zip 文件)。
pack200 (and gzip) produces much smaller files than jars (effectively zip files).
试试这个工具。 http://proguard.sourceforge.net/
try this tool. http://proguard.sourceforge.net/
据我所知,您无法从 Java 类文件中删除符号,但您可以缩短标识符。然而,这可能会使堆栈跟踪变得毫无用处,所以我不提倡这样做。
但是,您可以通过使用 AdvanceCOMP 项目(.jar 档案只是内部的普通 .zip 文件)。
As far as I can tell you can't strip symbols from Java class files, but you can shorten identifiers. However, this will probably make stack traces useless, so I don't advocate it.
However you can losslessly reduce file size by recompressing your .jar files using improved deflate algorithms from the AdvanceCOMP project (.jar archives are just plain .zip files inside).
您可以使用工具来应用代码混淆。这通常会缩小变量和方法名称并显着减少类大小。将代码部署到 J2ME 平台时通常会这样做。
You could use a tool to apply code obfuscation. This will often shrink down the variable and method names and reduce the class sizes significantly. This is often done when deploying code to the J2ME platform.
HTTP 压缩通常只比 JAR 压缩消耗 50%-80% 的带宽,特别是当您创建大量类(例如 Scala 程序)时。
The HTTP compression usually only consumes 50%-80% bandwidth than JAR compression, especially when you created lots of classes, e.g. a Scala program.
如果使用 NetBeans,则可以在项目配置中(在“Build”->“Packaging”下)设置构建脚本来生成压缩的 JAR 文件。也许不如其他解决方案那么有效,但它只是一个复选框的距离。 :-)
If you use NetBeans, you can set the build script to generate a compressed JAR file in the project configuration (under Build->Packaging). Maybe not as effective as other solutions, but it's only a checkbox away. :-)