Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds support for counting agent jar classes in memory calculator
Browse files Browse the repository at this point in the history
pivotal-david-osullivan committed May 4, 2022
1 parent c581db8 commit e5330d1
Showing 4 changed files with 61 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -13,3 +13,4 @@
# limitations under the License.

bin/
.DS_Store
2 changes: 1 addition & 1 deletion count/count_classes.go
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ import (
"strings"
)

var ClassExtensions = []string{".class", ".clj", ".groovy", ".kts"}
var ClassExtensions = []string{".class", ".classdata", ".clj", ".groovy", ".kts"}

func Classes(path string) (int, error) {
file := filepath.Join(path, "lib", "modules")
47 changes: 38 additions & 9 deletions helper/memory_calculator.go
Original file line number Diff line number Diff line change
@@ -18,8 +18,10 @@ package helper

import (
"fmt"
"github.com/mattn/go-shellwords"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
@@ -75,6 +77,12 @@ func (m MemoryCalculator) Execute() (map[string]string, error) {
}
}

var values []string
opts, ok := os.LookupEnv("JAVA_TOOL_OPTIONS")
if ok {
values = append(values, opts)
}

if s, ok := os.LookupEnv("BPL_JVM_LOADED_CLASS_COUNT"); ok {
if c.LoadedClassCount, err = strconv.Atoi(s); err != nil {
return nil, fmt.Errorf("unable to convert $BPL_JVM_LOADED_CLASS_COUNT=%s to integer\n%w", s, err)
@@ -94,6 +102,11 @@ func (m MemoryCalculator) Execute() (map[string]string, error) {
}
}

agentClassCount, err := CountAgentClasses(opts)
if err != nil {
return nil, err
}

staticAdjustment := 0
adjustmentFactor := uint64(100)
if adj, ok := os.LookupEnv("BPL_JVM_CLASS_ADJUSTMENT"); ok {
@@ -110,12 +123,12 @@ func (m MemoryCalculator) Execute() (map[string]string, error) {

appClassCount, err := count.Classes(appPath)

totalClasses := float64(jvmClassCount+appClassCount+staticAdjustment) * (float64(adjustmentFactor) / 100.0)
totalClasses := float64(jvmClassCount+appClassCount+agentClassCount+staticAdjustment) * (float64(adjustmentFactor) / 100.0)

if err != nil {
return nil, fmt.Errorf("unable to determine class count\n%w", err)
}
m.Logger.Debugf("Memory Calculation: (%d%% * (%d + %d + %d)) * %0.2f", adjustmentFactor, jvmClassCount, appClassCount, staticAdjustment, ClassLoadFactor)
m.Logger.Debugf("Memory Calculation: (%d%% * (%d + %d + %d + %d)) * %0.2f", adjustmentFactor, jvmClassCount, appClassCount, agentClassCount, staticAdjustment, ClassLoadFactor)
c.LoadedClassCount = int(totalClasses * ClassLoadFactor)
}

@@ -154,13 +167,7 @@ func (m MemoryCalculator) Execute() (map[string]string, error) {
c.TotalMemory = calc.Size{Value: totalMemory}
}

var values []string
s, ok := os.LookupEnv("JAVA_TOOL_OPTIONS")
if ok {
values = append(values, s)
}

r, err := c.Calculate(s)
r, err := c.Calculate(opts)
if err != nil {
return nil, fmt.Errorf("unable to calculate memory configuration\n%w", err)
}
@@ -220,3 +227,25 @@ func parseMemInfo(s string) (int64, error) {
}
return num * unit, nil
}

func CountAgentClasses(opts string) (int, error) {
var agentClassCount int
if p, err := shellwords.Parse(opts); err != nil {
return 0, fmt.Errorf("unable to parse $JAVA_TOOL_OPTIONS\n%w", err)
} else {
var agentPaths []string
for _, s := range p {
if strings.HasPrefix(s, "-javaagent:") {
agentPaths = append(agentPaths, strings.Split(s, ":")[1])
}
}
for _, path := range agentPaths {
if c, err := count.Classes(filepath.Dir(path)); err == nil {
agentClassCount += c
} else {
return 0, fmt.Errorf("unable to count classes of agent jar at %s\n%w", path, err)
}
}
}
return agentClassCount, nil
}
21 changes: 21 additions & 0 deletions helper/memory_calculator_test.go
Original file line number Diff line number Diff line change
@@ -17,8 +17,10 @@
package helper_test

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"testing"

@@ -361,6 +363,25 @@ func testMemoryCalculator(t *testing.T, context spec.G, it spec.S) {
})
})

context("$JAVA_TOOL_OPTIONS with agents", func() {
it.Before(func() {
Expect(os.Setenv("JAVA_TOOL_OPTIONS", fmt.Sprintf("-javaagent:%s", filepath.Join("../count/testdata", "stub-dependency.jar")))).To(Succeed())
})

it.After(func() {
Expect(os.Unsetenv("JAVA_TOOL_OPTIONS")).To(Succeed())
})

it("counts classes of agent jars supplied via $JAVA_TOOL_OPTIONS", func() {
c, err := helper.CountAgentClasses(os.Getenv("JAVA_TOOL_OPTIONS"))
Expect(err).NotTo(HaveOccurred())
Expect(c).To(Equal(2))
Expect(m.Execute()).To(Equal(map[string]string{
"JAVA_TOOL_OPTIONS": fmt.Sprintf("-javaagent:%s -XX:MaxDirectMemorySize=10M -Xmx522705K -XX:MaxMetaspaceSize=13870K -XX:ReservedCodeCacheSize=240M -Xss1M", filepath.Join("../count/testdata", "stub-dependency.jar")),
}))
})
})

context("user configured", func() {
it.Before(func() {
Expect(os.Setenv("JAVA_TOOL_OPTIONS", "-XX:MaxDirectMemorySize=10M -Xmx522705K -XX:MaxMetaspaceSize=13870K -XX:ReservedCodeCacheSize=240M -Xss1M")).To(Succeed())

0 comments on commit e5330d1

Please sign in to comment.