4
\$\begingroup\$

I'm writing small tool, which must execute jmap -heap, write output to log, then takes some data from log and calculate used memory.

I added some debug to it.

# JVM with jmap statistic
def java_heap_save(log):

  subprocess.call('jmap -heap %s > %s' % (java_pid, log), shell=True, stdout=devnull, stderr=devnull)

  with open(log, 'r') as logread:

    data = logread.readlines()

    # this is just to display 'what will parsing'
    print(data)

    # here is two list, first - index of item in data, second - for message on terminal
    nums = [40, 35, 30, 25, 20]
    messages = ['PS Perm Generation', 'PS Old Generation', 'Yong To Space', 'Yong From Space', 'Yong Eden Space']
    # I don't found how to create dynamic variable names, so use dictionary
    count_names = {}
    count_numbers = 1

    for num, mess in zip(nums, messages):
#      print(mess + ' used '+ str((int(data[num].split(' ')[-2]) / 1024)) + ' KB;')
       # from log we got data in bytes, convert here to megabatyes
       res = (int(data[num].split(' ')[-2]) / 1024)
       print('%s used %s KB;' % (mess, res))
       # save value
       count_names[count_numbers] = int(res)
       count_numbers += 1

    print('\nJVM Heap memory stats:\n')
    mem_total = (int(data[7].split(' ')[-2]) / 1024 / 1024)
    print('MemTotal = %s MB;' % mem_total)

    # next few lines - my first attempt, then was rewrited to loop above

#    ps_perm_gen = (int(data[40].split(' ')[-2]) / 1024)
#    print('PS Perm Generation used = %s KB;' % ps_perm_gen)
#    ps_old_gen = (int(data[35].split(' ')[-2]) / 1024)
#    print('PS Old Generation used = %s KB;' % ps_old_gen)
#    young_to_space = (int(data[30].split(' ')[-2]) / 1024)
#    print('Yong To Space used = %s KB;' % young_to_space)
#    young_from_space = (int(data[25].split(' ')[-2]) / 1024)
#    print('Yong From Space used = %s KB;' % young_from_space)
#    young_eden_space = (int(data[20].split(' ')[-2]) / 1024)
#    print('Yong Eden Space used = %s KB;' % young_eden_space)
#    heap_total_used = ((ps_perm_gen + ps_old_gen + young_to_space + young_eden_space) / 1024)

    # count total used memory
    heap_total_used = ((count_names[1] + count_names[2] + count_names[3] + count_names[4] + count_names[5]) / 1024)
    print('\nTotal heap used: %s MB;' % heap_total_used)
    # count % from total avail memory
    heap_percentage_used = heap_total_used * 100 / mem_total
    print('Heap percentage used: %s%%' % heap_percentage_used)

Then it is called like:

java_heap_save(jmap_log)

Output:

$ ./monitor.py
...
JUST FOR DEBUG

['\n', 'using thread-local object allocation.\n', 'Parallel GC with 2 thread(s)\n', '\n', 'Heap Configuration:\n', '   MinHeapFreeRatio = 40\n', '   MaxHeapFreeRatio = 70\n', '   MaxHeapSize      = 1073741824 (1024.0MB)\n', '   NewSize          = 1310720 (1.25MB)\n', '   MaxNewSize       = 17592186044415 MB\n', '   OldSize          = 5439488 (5.1875MB)\n', '   NewRatio         = 2\n', '   SurvivorRatio    = 8\n', '   PermSize         = 21757952 (20.75MB)\n', '   MaxPermSize      = 1073741824 (1024.0MB)\n', '\n', 'Heap Usage:\n', 'PS Young Generation\n', 'Eden Space:\n', '   capacity = 334626816 (319.125MB)\n', '   used     = 164795568 (157.1613006591797MB)\n', '   free     = 169831248 (161.9636993408203MB)\n', '   49.247567774126026% used\n', 'From Space:\n', '   capacity = 11927552 (11.375MB)\n', '   used     = 2293760 (2.1875MB)\n', '   free     = 9633792 (9.1875MB)\n', '   19.23076923076923% used\n', 'To Space:\n', '   capacity = 11337728 (10.8125MB)\n', '   used     = 0 (0.0MB)\n', '   free     = 11337728 (10.8125MB)\n', '   0.0% used\n', 'PS Old Generation\n', '   capacity = 715849728 (682.6875MB)\n', '   used     = 249838952 (238.2649917602539MB)\n', '   free     = 466010776 (444.4225082397461MB)\n', '   34.90103330737034% used\n', 'PS Perm Generation\n', '   capacity = 104005632 (99.1875MB)\n', '   used     = 95693760 (91.26068115234375MB)\n', '   free     = 8311872 (7.92681884765625MB)\n', '   92.00824816871456% used\n']


PS Perm Generation used 93450 KB;
PS Old Generation used 243983 KB;
Yong To Space used 0 KB;
Yong From Space used 2240 KB;
Yong Eden Space used 160933 KB;

JVM Heap memory stats:

MemTotal = 1024 MB;

Total heap used: 488 MB;
Heap percentage used: 47%

What I can improve here?

In fact - I don't like how I realized 'log read' code, I mean this:

int(data[SOME_NUMBER_HERE_ENTERED_MANUALLY].split(' ')[-2]) / 1024)

CentOS 6,5, Python 2.6

\$\endgroup\$
3
\$\begingroup\$

First off, using % for string formatting is deprecated if you're using Python 2.6 or higher. You should be using str.format instead. Here's an example of how you can use str.format.

# str.format without positional or named parameters
print "{} {}".format("Hello", "world")

# str.format with positional parameters
print "{1} {0}".format("world", "Hello")

# str.format with named paramters
print "{word1} {word2}".format(word1="Hello", word2="world")

Secondly, all the commented out lines of code, like # ps_perm_gen = (int(data[40].split(' ')[-2]) / 1024) should be entirely removed. Stuff like this is an eyesore to look at.

You also have a lot of not-so-great variable names. A few examples include nums, res, data, and count_numbers, Variable names should describe the purpose of the variable as best as possible.

Finally, improve your comments. Right now, not very many of your comments are very good. A few examples include:

# next few lines - my first attempt, then was rewrited to loop above
# this is just to display 'what will parsing'
# save value

Comments should describe hard-to-understand parts of code in detail, but only if needed. If the code is clear enough to understand, then don't use a comment.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.