View difference between Paste ID: rY3gPVGE and 8LYm2EMj
SHOW: | | - or go back to the newest paste.
1
#!/bin/bash
2
# This line is for starting from mac os icon double click
3
cd "$( dirname "$0" )" 
4
5
# V1.7.1. Minor tweaks:
6
# - compile threshold lowered from 3,000 to 300. Oracle's default for servers is 15,000;
7
#   my testing fails to show any benefit from this. Faster startup, quicker initial block
8
#   breaking, etc.
9
# - Initial memory allocation lowered
10
# - Clarification to the comments at the end where you select "favor extra space for tenured"
11
#   or "favor extra space for new" memory.
12
# - MinHeapFreeRatio=21 instead of 20 -- solves a borderline issue where 80% of memory was
13
#   used, 20% was free, and repeated full CMS collections were run without expanding memory
14
#   allocation to java.
15
# - Keep one old GC.log file around.
16
# - Changed from "Release Candidate" to "Official first release" :-).
17
18
# V1.7: Borderline case existed where memory allocation would be in error.
19
# Example: Survivor copy of 90, 90% => Survivor space of 100.
20
# Desired Eden of 250.
21
# Would attempt to allocate 200 for eden, 200 for two survivors.
22
# That's 400 for new, even if "MaxNew" was 350.
23
24
# Right behavior in this case?
25
# No clear answer.
26
# What's more important: making sure you have as much eden as you ask for,
27
# or limiting your "new" memory?
28
#
29
# Answer used here: "new" memory is more important than tenured,
30
# as long as tenured is big enough. So, if that happens, we force maxnew up to fit.
31
# When this happens, a warning is printed. Pay attention to your logs when this
32
# happens -- tenured overflow results in very large amounts of full collections
33
# because small collections cannot clear eden.
34
35
## V1.6. This time the 64 bit flag works.
36
# Again: This is throwing "too much" memory at eden/survivor.
37
# Pay attention to the GC log. Sections like
38
39
# 1552.959: [CMS-concurrent-reset-start]
40
# 1552.965: [CMS-concurrent-reset: 0.005/0.005 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
41
# {Heap before GC invocations=17 (full 1):
42
#  par new generation   total 180224K, used 146721K [0000000009000000, 0000000016c00000, 0000000025200000)
43
#   eden space 135168K, 100% used [0000000009000000, 0000000011400000, 0000000011400000)
44
#   from space 45056K,  25% used [0000000014000000, 0000000014b48750, 0000000016c00000)
45
#   to   space 45056K,   0% used [0000000011400000, 0000000011400000, 0000000014000000)
46
#  concurrent mark-sweep generation total 102400K, used 63696K [0000000025200000, 000000002b600000, 000000003b000000)
47
#  concurrent-mark-sweep perm gen total 24940K, used 21197K [000000003b000000, 000000003c85b000, 0000000044600000)
48
49
# The "CMS-concurrent-reset" means it has finished a full collection.
50
# The "concurrent mark-sweep generation" line has the tenured allocation
51
# In this case, 63 MB of long-term data.
52
53
# Sections like
54
55
# 56.089: [GC 56.089: [ParNew
56
# Desired survivor size 41523608 bytes, new threshold 4 (max 4)
57
# - age   1:   17033216 bytes,   17033216 total
58
# - age   2:   22458216 bytes,   39491432 total
59
# - age   3:      14552 bytes,   39505984 total
60
# - age   4:     136648 bytes,   39642632 total
61
62
# 17 MB of temporary space was recently allocated; just under 40 MB of temporaries are "surviving"
63
# and not immediately useless. (This comes from startup; almost all of that will be valid for the life
64
# of the program run.)
65
66
# Age 4 overflows (age 4's total larger than the max, or worse, "new threshold 2" or other small number)
67
# means the potential for tenured space to grow unnecessarily. This kills long-term performance.
68
69
## V1.5-corrected: 64 bit version, and ** LOTS OF MEMORY ALLOCATION **
70
# This is to give information for data collection.
71
# Determine how much your system uses, and then adjust numbers down to avoid waste
72
#
73
# Specifically: By making the memory pools large, we see how much is used.
74
# Then, we can determine what to cut them down to.
75
#
76
# This will probably be the last CMS version; G1GC next.
77
78
java=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Commands/java
79
80
## V1.4: Java is now customizable (see the above line), thank you oracle for a
81
## java (1.7) that does not support 32 bit servers for reduced memory consumption. 
82
83
## V1.3: The -XX:SoftRefLRUPolicyMSPerMB=0 flag got lost! Back in now.
84
## This flag defaults to 1000, and can cause memory leaks.
85
86
## V1.2: We now play with -XX:TargetSurvivorRatio=n to reduce waste in new, permitting more
87
## space to be used
88
89
# Configurables:
90
# -d32 is for heap size up to 2.5gb. (NB: apparently only 1.5 gb on microsoft windows?)
91
# Change to "-d64 XX:+UseCompressedOops" if you use more.
92
# ** Mention that flag specifically, do not rely on it being autoset.
93
# ** Known and documented JVM bug -- https://forums.oracle.com/forums/thread.jspa?messageID=10017916
94
95
JVM_SIZE="-d32 -server"
96
# JVM_SIZE="-d64 -XX:+UseCompressedOops -server"
97
98
# CMSInitiatingOccupancyFraction: Determine how frequently to do a full CMS
99
# Special: New "Most important". This primarily affects long-term growth
100
# of the heap. The percentage of used space before CMS starts a collection.
101
# 95 is sufficient for general stuff. 85 is useful for things that suddenly
102
# need a lot.
103
# Dynamic maps, in particular, no longer needs 125 MB of survivor -- it can
104
# get by with 60-75. It can go much lower, but then the garbage collections
105
# need to be started sooner, or else it will never have enough memory and
106
# always grow the heap.
107
#
108
# To clarify: This is obsolete -- completely -- in G1GC. 
109
# This needs to be low enough that sudden spurts of temporary memory trigger
110
# garbage collection first. 
111
# This should be re-worked as a "MB safety level" -- for example, if you have
112
# 300 MB of tenured, and want at least 30 MB free. But Java don't work that way.
113
# As tenured increases, this will also increase the "keep free" level.
114
CMSInitiatingOccupancyFraction=80
115
116
# Memory tuning:
117
# Command line controls total heap, and "new". "Tenured" is the difference.
118-
MAX=1300
118+
119
120
# These numbers are in "Megabytes", the java "m" suffix.
121
122
# The rule of memory tuning:
123
# SurvivorSpace * (SurvivorRatio + 2) = New
124
# ("SurvivorSpace" is twice the actual surviving threshold.)
125
# SurvivorSpace * SurvivorRatio = Eden.
126
# Two additional survivor spaces are used to copy surviving objects across minor collections.
127
128-
Tenured=500
128+
129
# Does not include permanent (byte/compiled code)
130-
# Most important tuning number. Survivor.
130+
131
MAX=550
132
133
# Tenured: Desired long-term storage space
134
# Will vary based on mods, and "loaded chunks"
135
# -- how many parties of players close to each other.
136
#
137-
# *** This should be enough for generation 3 95%+ of the time. ***
137+
138
# of players near each other. 
139
#
140
# That is a guess. Please report what numbers work for your server.
141
# 
142
# ** More testing. 
143
# Multiple people in the same area: No detectable difference between 1 and 2 people.
144
# Actual space needed varied from (LDS minimum) 55 (1.5.1) to 75 (1.4.7, dynamic maps)
145
# The old guess of 250 was way too high.
146
147
# This will need to be higher on servers with more players.
148
Tenured=100
149
150
151
# Most important tuning number. Survivor copy size.
152
# Making this higher: Fewer full collections, but more wasted space.
153
# During startup, expect this to overflow frequently.
154
# Actual space allocated is 2 spaces, each one twice this size.
155
# "waste/overhead" will be two about to three times this number.
156
# *** Maximum of 1/6rd of "new" 
157
# Pay attention to the tenuring distribution logs. 
158
# *** This should be enough for generation 3 99%+ of the time. ***
159
# ** TOO SMALL WILL KILL YOUR GARBAGE COLLECTION **
160
# (worse, it will cause tenured space to grow.)
161
# ** TOO BIG WILL WASTE SPACE **
162
# (this is a minor issue overall.)
163
#
164
# To clarify: You can easily use 12 here if you stay primarily in one place.
165
# You can even use less, but the memory savings are not significant.
166
# Biggest usage I've seen: dimension travel (see below) and dynamic maps with
167-
# SurvivorCopySize=65
167+
168-
SurvivorCopySize=100
168+
169
# *** Recommendations
170
# If you do a lot of dimension travel -- including using a nether hub to get
171
# around, or lots of Mystcraft books (two links to go from A to B in the same
172
# world), then you want 65 MB if you can afford it, or 53 MB minimum. That's
173
# for one person; groups will be higher.
174
# (tested in a world with forests at the hub zone; may be higher for extreme hills,
175
# jungles, or jungle-hills (expected to be the worst case.))
176
#
177
# If you do a lot of high speed rail travel over large distances, a minimum of
178
# 40 MB. Ditto if you use a lot of flight mode movement. More if you have a
179
# speed boost.
180
#
181
# If you do very little travel -- if you are just building in one spot -- then
182
# 15 MB is plenty.
183
#
184
# If you are testing a new mod pack, and have no clue what you need, start at 100.
185
# If you are working with a multiplayer server, I don't know what to advise --
186-
# should be less than this 98% of the time.
186+
187
#
188
# More testing: 147, dynamic maps, ocean area: 30
189
# 151, jungles/desert/forest: 38
190
191
# Probably are good at 32 here
192
# Defaulting to 35 MB, works well on a server with extreme hills and no massive dimension
193
# travel. Again: Changing dimension once every few minutes won't bother anything. Rapid
194
# changing multiple times a minute will.
195
196
SurvivorCopySize=35
197
198
# Survivor target ratio. Java defaults to 50%, which wastes a lot of space. If you know how much
199
# you need (see below), you can set this value higher; this gives less waste and "better performance".
200
201
TargetSurvivorRatio=90
202
203
## Notes on "SurvivorCopySize":
204
# Flying around in creative mode, in already generated chunks will want
205
#   at least 30-35, preferrably 40 meg.
206
# Standing around, single player, can be happy with less than 1.
207
# Even in Mystcraft, with massive amounts of decay everywhere (implies lots of block
208
# updates), 95% of the time 1 meg suffices.
209
# Moving around a little, doing basic building/digging, about 3.
210
#
211
# The rule: You want to see "new threshold 4 (max 4)" most of the time.
212
# The total value at age three -- 
213
# - age   3:      36712 bytes,    5897520 total
214-
desiredEden=250
214+
# should be less than this almost all of the time, at least after startup.
215
#
216
# 12 meg is more than enough for one person with EBXL, Mystcraft, Twilight Forest,
217
# and Custom Ore Gen. Even in EBXL's extreme jungle with Mystcraft's decay littering the ground.
218
#
219
# The single biggest factor is chunks loaded; that will depend more on parties than on players,
220
# and the speed at which they move. Adjust to your server, and your mods. Remember, teleportation
221
# will raise this value very rapidly.
222
#
223
# To clarify the problem: An overflow here forces memory into tenured space. If tenured is
224
# nearly full -- lets say Java will start a garbage collection soon -- then this can force
225
# more space to be allocated to tenured.
226
#
227
# Forcing more space into tenured is the disaster that this is all about preventing.
228
# Tenured space is more expensive to collect, and Java does not release this back to the
229
# operating system when it does not need it. This means, on systems that are doing more than
230
# just a minecraft server (say, a client, a browser, perhaps voice chat software, etc), this
231
# will impact your whole system's performance.
232
#
233
# A secondary effect of overflow is forcing earlier/more frequent full collections.
234
# For single/dual processors, this may be the more dominant factor.
235
# For 4/8 core processors, this is minor.
236
237
# Second most important tuning. Eden.
238
# Making this bigger means less frequent small collections.
239
# General rule: Make this as big as your memory can handle.
240
# Must be at least 2x Survivor. Java requires it to be
241
# an integer multiple of Survivor.
242
#
243
# If you have no idea what to use here, then right at the end
244
# there are a pair of commended lines that will calculate
245
# something for you. That calculation uses Max, Tenured, and
246
# copy, and assumes everything else is new/Eden. Result is a
247
# bigger footprint (should always use max or close to it) and
248
# the biggest eden space available.
249
#
250
# Specifying a value here will reduce the starting eden, and
251
# give space for tenured to grow later.
252
253
desiredEden=30
254
255
# Summary: Approximately desiredEden, plus 2 times Survivor,
256
# plus 130, will be used by java to start the heap. Up to a max of MAX. 
257
# Script will attempt to ensure at least Tenured space exist;
258
# should exit with a message if it cannot.
259
#
260
# In theory, Java will allocate extra space to new or tenured as needed.
261
# In practice, I've never seen it increase "new".
262
#
263
# See the bottom of the config section for more.
264
265
# If your shell cannot do math, replace these with an appropriate constant
266
267
MaxNew=$(($MAX - $Tenured))
268
269
## Survivor=$((2 * $SurvivorCopySize))
270
## Working with survivor target. "2" is for 50%. For 90%, it's much closer to 1.
271
## What we want is 100 / target percentage, as the ratio instead of 2.
272
## For integer only shell math, we re-write as (100 * survivor) / target, which gives us
273
## close integer to the desired result -- as close as we can get in the shell.
274
275
Survivor=$(( ($SurvivorCopySize * 100 ) / $TargetSurvivorRatio ))
276
277
## Equally, the "3" in sanity test is from 3 bins -- two survivors, one eden.
278
## But that does NOT change here -- it's still the sanity test lower limit.
279
280
sanityTest=$((3 * $Survivor))
281
if [ $sanityTest -gt $MaxNew ]
282
then
283
	echo Memory config error >& 2
284
	exit 1
285
fi
286
287
# We cannot use more than MaxNew.
288
289
# The idea:
290
# 1. Find the multiple of Survivor that is bigger than S and less than MN.
291
# 2. Determine survivor ratio from that. Subtract 2 (java.)
292-
# New space is sufficient -- specified eden.
292+
293
294
# "New" will be Eden plus 2* Survivor.
295
296-
# borderline case: Not quite the desired eden, we ran into maxnew.
296+
297-
# Disable these; we'd rather raise maxNew for Minecraft.
297+
298-
## NEW=$biggerNew
298+
299-
## RATIO=$MaxRatio
299+
300
desiredRatio=$(( ($desiredEden / $Survivor)  ))
301
302
# SurvivorSpace * (SurvivorRatio + 2) = New
303
304
# Now check for "desired Eden". If survivor is not an exact multiple of DE,
305
# then we have just rounded down. Test for this, and if so, see if we can
306
# raise it up (watch out for maxnew)
307
308
## TODO! FIXME! This is a cheap approximation
309
if ( [ $(( $desiredRatio + 1 )) -le $MaxRatio ] )
310-
START=$(($NEW + 130))
310+
311
fi
312-
# 130 MB of tenured space to have Java "happy". Less just results in repeated
312+
313-
# full collections while Java raises the amount of allocated memory. 
313+
314
biggerNew=$(($Survivor * ($MaxRatio + 2) ))
315
316
echo Debug: Max ratio $MaxRatio, desiredRatio $desiredRatio
317
echo Debug: biggerNew $biggerNew, should be less than MaxNew $MaxNew
318
echo Debug: desired eden $desiredEden, survivor $Survivor, actual new $desiredNew
319
320
# desiredNew: Gives an eden up to, not bigger, than desiredEden.
321
# biggerNew: Gives an eden at least as big as desiredEden.
322
# FIXME: DesiredNew / ratio should be smallest at least as big as desiredEden
323
# This means, if less, then add 1 to ratio and add to new.
324
#
325
# "Bigger" assigns ALL non-tenured memory to new.
326
327
# Q: Desired numbers? Bigger/Max numbers?
328
329
# Choose one of these pairs
330
331
# Use the user specified Eden. Starting memory footprint will be smaller.
332
# Tenured can grow if needed.
333
334-
	-XX:NewSize=${NEW}m -XX:MaxNewSize=${MaxNew}m \
334+
335
RATIO=$desiredRatio
336
337
# If you have no idea what values to use for Eden, then this will determine
338-
	-XX:CompileThreshold=3000 \
338+
# eden values on it's own. This will use your specified tenured, max, and
339
# copy values, and assign close to the maximum footprint and eden space.
340
341
# NEW=$biggerNew
342
# RATIO=$MaxRatio
343
344-
	-XX:MaxHeapFreeRatio=20 \
344+
345-
	-XX:MinHeapFreeRatio=15 \
345+
346
then
347
	MaxNew=$NEW
348
	## CAUTION! "Start" below may fail.
349
	## If you get here, then you need to watch out for tenured overflow
350-
	-jar new_server.jar nogui 151myst10.3
350+
351
fi
352-
# The last word of that exec statement -- '151myst10.3' -- is just something that shows up in
352+
353
START=$(($NEW + 90))
354
# Experimal behavior: Starting up, and loading one person into a world, takes
355
# about 70-90 MB of tenured space to have Java "happy". Less just results in repeated
356
# full collections while Java raises the amount of allocated memory. (Range depends on
357
# mods.)
358
359
## TESTME: Does "MaxNewSize" matter if we have adaptive GC boundary? Does it hurt?
360
361
# A few more notes ...
362
363
# -XX:+UseAdaptiveGCBoundary -- apparently, adjust the boundary between new and tenured as needed.
364
# Nice to see; did not know about it before. 
365
# Sadly, it seems to have no effect.
366
367
# -XX:+CMSIncrementalMode: Tells the garbage collector to break the job into many small parts.
368
# May result in better performance. Essential on systems with few cores.
369
370
# -XX:CompileThreshold: Tells Java when to convert bytecode into compiled code.
371
# Server defaults to something like 15,000, which is appropriate for something that will
372
# run for months, and horrible for something that will run for a few hours.
373
# Non-server defaults to ... 1000? 1500? Much lower.
374
375
# "-f" prevents an error message on the first run
376
mv -f GC.log GC.log.old
377
378
exec $java \
379
	$JVM_SIZE \
380
	-Xms${START}m -Xmx${MAX}m \
381
	-XX:+UseAdaptiveGCBoundary \
382
	-XX:TargetSurvivorRatio=$TargetSurvivorRatio \
383
 	-XX:NewSize=${NEW}m -XX:MaxNewSize=${MaxNew}m \
384
	-XX:SurvivorRatio=$RATIO \
385
	-XX:CompileThreshold=300 \
386
	-XX:+UseConcMarkSweepGC -XX:+UseParNewGC \
387
	-XX:CMSInitiatingOccupancyFraction=$CMSInitiatingOccupancyFraction \
388
\
389
	-XX:SoftRefLRUPolicyMSPerMB=0 \
390
	-XX:MaxPermSize=150m \
391
	-XX:+UseParNewGC \
392
	-XX:MaxHeapFreeRatio=25 \
393
	-XX:MinHeapFreeRatio=21 \
394
	-XX:+DisableExplicitGC \
395
	-XX:MaxTenuringThreshold=4 \
396
	-XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution \
397
	-XX:+PrintCommandLineFlags -XX:+PrintGCDetails -Xloggc:GC.log \
398
	-jar new_server.jar nogui 147Main
399
400
401
# The last word of that exec statement -- '147Main' -- is just something that shows up in
402
# the process list, so I can tell which process is which server (each copy of this script
403
# has a different name in that field).